Permalink
Browse files

Basic support for parsing with REXML rather than Nokogiri if Nokogiri…

… isn't available, or not appropriate (JRuby Nokogiri not ready yet).
  • Loading branch information...
gkellogg committed Oct 8, 2011
1 parent 8531ca6 commit db02c8ec47e1968f8e6ee0ab4ee5f40fc4e269ff
View
@@ -11,7 +11,7 @@ RDF::RDFa parses [RDFa][RDFa 1.1 Core] into statements or triples.
* Fully compliant RDFa 1.1 parser.
* Template-based Writer to generate XHTML+RDFa.
* Writer uses user-replacable [Haml][Haml]-based templates to generate RDFa.
-* Uses Nokogiri for parsing HTML/SVG
+* If available, Uses Nokogiri for parsing HTML/SVG, falls back to REXML otherwise (and for JRuby)
* [RDFa tests][RDFa-test-suite] use SPARQL for most tests due to Rasqal limitations. Other tests compare directly against N-triples.
Install with 'gem install rdf-rdfa'
@@ -298,8 +298,8 @@ The template hash defines four Haml templates:
## Dependencies
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.3.1)
-* [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.3.3)
* [Haml](https://rubygems.org/gems/haml) (>= 3.0.0)
+* Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.3.3)
## Documentation
Full documentation available on [Rubydoc.info][RDFa doc]
@@ -1,120 +0,0 @@
-# Use Nokogiri when available, and REXML otherwise:
-begin
- require 'nokogiri'
-rescue LoadError => e
- require 'rexml/document'
-end
-
-module RDF; class Literal
- ##
- # An XML literal.
- #
- # XML Literals are maintained in a lexical form, unless an object form is provided.
- # The both lexical and object forms are presumed to be in Exclusive Canonical XML.
- # As generating this form is dependent on the context of the XML Literal from the
- # original document, canonicalization cannot be performed directly within this
- # class.
- #
- # @see http://www.w3.org/TR/rdf-concepts/#section-XMLLiteral
- # @see http://www.w3.org/TR/rdfa-core/#s_xml_literals
- # @see http://www.w3.org/TR/xml-exc-c14n/
- # @since 0.2.1
- class XML < Literal
- ##
- # @param [Object] value
- # @option options [String] :lexical (nil)
- # @option options [:nokogiri, :rexml] :library
- # Library to use, defaults to :nokogiri if available, :rexml otherwise
- def initialize(value, options = {})
- @datatype = options[:datatype] || DATATYPE
- @string = options[:lexical] if options.has_key?(:lexical)
- if value.is_a?(String)
- @string ||= value
- else
- @object = value
- end
-
- @library = options[:library] ||
- case
- when defined?(::Nokogiri) then :nokogiri
- else :rexml
- end
- end
-
- ##
- # Parse value, if necessary
- #
- # @return [Object]
- def object
- @object ||= case @library
- when :nokogiri then parse_nokogiri(value)
- when :rexml then parse_rexml(value)
- end
- end
-
- def to_s
- @string ||= @object.to_s
- end
-
- ##
- # XML Equivalence. XML Literals can be compared with each other or with xsd:strings
- #
- # @param [Object] other
- # @return [Boolean] `true` or `false`
- #
- # @see http://www.w3.org/TR/rdf-concepts/#section-XMLLiteral
- def eql?(other)
- if other.is_a?(Literal::XML)
- case @library
- when :nokogiri then equivalent_nokogiri(other)
- when :rexml then equivalent_rexml(other)
- end
- elsif other.is_a?(Literal) && (other.plain? || other.datatype == RDF::XSD.string)
- value == other.value
- else
- super
- end
- end
-
- private
-
- # Nokogiri implementations
- if defined?(::Nokogiri)
- ##
- # Parse the value either as a NodeSet, as results are equivalent if it is just a node
- def parse_nokogiri(value)
- Nokogiri::XML.parse("<root>#{value}</root>").root.children
- end
-
- # Use equivalent-xml to determine equivalence
- def equivalent_nokogiri(other)
- require 'equivalent-xml'
- res = EquivalentXml.equivalent?(object, other.object)
- res
- end
- end
-
- ##
- # Parse the value either as a NodeSet, as results are equivalent if it is just a node
- def parse_rexml(value)
- REXML::Document.new("<root>#{value}</root>").root.children
- end
-
-
- # Simple equivalence test for REXML
- def equivalent_rexml(other)
- begin
- require 'active_support/core_ext'
- rescue LoadError => e
- # string equivalence
- end
-
- if Hash.respond_to?(:from_xml)
- Hash.from_xml(value) == Hash.from_xml(other.value)
- else
- # Poor mans equivalent
- value == other.value
- end
- end
- end # class XML
-end; end
View
@@ -1,5 +1,6 @@
require 'nokogiri' # FIXME: Implement using different modules as in RDF::TriX
require 'rdf/ntriples'
+require 'rdf/xsd'
module RDF::RDFa
##
@@ -232,6 +233,7 @@ def initialize(input = $stdin, options = {}, &block)
when nil
# Use Nokogiri when available, and REXML or Hpricot otherwise:
begin
+ raise LoadError, "Don't use java-native Nokogiri" if RUBY_PLATFORM == 'java'
require 'nokogiri'
:nokogiri
rescue LoadError => e
@@ -246,18 +248,18 @@ def initialize(input = $stdin, options = {}, &block)
require "rdf/rdfa/reader/#{@library}"
@implementation = case @library
when :nokogiri then Nokogiri
- #when :rexml then REXML
+ when :rexml then REXML
end
self.extend(@implementation)
detect_host_language_version(input, options)
- initialize_xml(input, options)
+ initialize_xml(input, options) rescue raise RDF::ReaderError.new($!.message)
if (root.nil? && validate?)
add_error(nil, "Empty document", RDF::RDFA.DocumentError)
raise RDF::ReaderError, "Empty Document"
end
- add_warning(nil, "Syntax errors:\n#{@doc.errors}", RDF::RDFA.DocumentError) if !@doc.errors.empty? && validate?
+ add_warning(nil, "Syntax errors:\n#{doc_errors}", RDF::RDFA.DocumentError) if !doc_errors.empty? && validate?
# Section 4.2 RDFa Host Language Conformance
#
@@ -283,7 +285,7 @@ def initialize(input = $stdin, options = {}, &block)
@host_defaults[:profiles] = [XML_RDFA_PROFILE, XHTML_RDFA_PROFILE]
end
- add_info(@doc, "version = #{@version}, host_language = #{@host_language}")
+ add_info(@doc, "version = #{@version}, host_language = #{@host_language}, library = #{@library}")
block.call(self) if block_given?
end
@@ -432,33 +434,33 @@ def process_profile(element, profiles)
profiles.
map {|uri| uri(uri).normalize}.
each do |uri|
- # Don't try to open ourselves!
- if base_uri == uri
- add_debug(element, "process_profile: skip recursive profile <#{uri}>")
- next
- end
+ # Don't try to open ourselves!
+ if base_uri == uri
+ add_debug(element, "process_profile: skip recursive profile <#{uri}>")
+ next
+ end
- old_debug = RDF::RDFa.debug?
- begin
- add_info(element, "process_profile: load <#{uri}>")
- RDF::RDFa.debug = false
- profile = Profile.find(uri)
- rescue Exception => e
- RDF::RDFa.debug = old_debug
- add_error(element, e.message, RDF::RDFA.ProfileReferenceError)
- raise # In case we're not in strict mode, we need to be sure processing stops
- ensure
- RDF::RDFa.debug = old_debug
- end
+ old_debug = RDF::RDFa.debug?
+ begin
+ add_info(element, "process_profile: load <#{uri}>")
+ RDF::RDFa.debug = false
+ profile = Profile.find(uri)
+ rescue Exception => e
+ RDF::RDFa.debug = old_debug
+ add_error(element, e.message, RDF::RDFA.ProfileReferenceError)
+ raise # In case we're not in strict mode, we need to be sure processing stops
+ ensure
+ RDF::RDFa.debug = old_debug
+ end
- # Add URI Mappings to prefixes
- profile.prefixes.each_pair do |prefix, value|
- prefix(prefix, value)
+ # Add URI Mappings to prefixes
+ profile.prefixes.each_pair do |prefix, value|
+ prefix(prefix, value)
+ end
+ yield :uri_mappings, profile.prefixes unless profile.prefixes.empty?
+ yield :term_mappings, profile.terms unless profile.terms.empty?
+ yield :default_vocabulary, profile.vocabulary if profile.vocabulary
end
- yield :uri_mappings, profile.prefixes unless profile.prefixes.empty?
- yield :term_mappings, profile.terms unless profile.terms.empty?
- yield :default_vocabulary, profile.vocabulary if profile.vocabulary
- end
end
# Extract the XMLNS mappings from an element
Oops, something went wrong.

0 comments on commit db02c8e

Please sign in to comment.