@@ -30,12 +30,16 @@ class EvaluationContext
3030 attr_accessor :language
3131 attr_accessor :graph
3232 attr_accessor :li_counter
33+ attr_accessor :direction
34+ attr_accessor :version # RDF Version, mirrored here
3335
34- def initialize ( base , element , graph , &cb )
36+ def initialize ( base , element , graph , version : nil , &cb )
3537 # Initialize the evaluation context, [5.1]
3638 self . base = RDF ::URI ( base )
3739 @uri_mappings = { }
3840 @language = nil
41+ @direction = nil
42+ @version = version
3943 @graph = graph
4044 @li_counter = 0
4145
@@ -47,6 +51,8 @@ def clone(element, **options, &cb)
4751 new_ec = EvaluationContext . new ( @base , nil , @graph )
4852 new_ec . uri_mappings = self . uri_mappings . clone
4953 new_ec . language = self . language
54+ new_ec . direction = self . direction
55+ new_ec . version = self . version
5056
5157 new_ec . extract_from_element ( element , &cb ) if element
5258
@@ -68,6 +74,12 @@ def extract_from_ancestors(el, &cb)
6874 # Extract Evaluation Context from an element
6975 def extract_from_element ( el , &cb )
7076 self . language = el . language if el . language
77+ # Direction only used in RDF 1.2 or greater
78+ self . direction = el . direction if el . direction && self . version . to_s >= "1.2"
79+ # Direction requires the appropriate ITS version
80+ if el . direction && el . its_version != '2.0'
81+ # XXX raise error?
82+ end
7183 if b = el . base
7284 b = RDF ::URI ( b )
7385 self . base = b . absolute? ? b : self . base . join ( b )
@@ -100,7 +112,7 @@ def base=(b)
100112 end
101113
102114 def inspect
103- v = %w( base subject language ) . map { |a | "#{ a } ='#{ self . send ( a ) . nil? ? 'nil' : self . send ( a ) } '" }
115+ v = %w( base subject language direction ) . map { |a | "#{ a } ='#{ self . send ( a ) . nil? ? 'nil' : self . send ( a ) } '" }
104116 v << "uri_mappings[#{ uri_mappings . keys . length } ]"
105117 v . join ( "," )
106118 end
@@ -112,6 +124,11 @@ def inspect
112124 # @return [Module]
113125 attr_reader :implementation
114126
127+ # Version of RDF to use. Currently, only "1.2" is defined.
128+ # @!attribute [r] version
129+ # @return [String]
130+ attr_reader :version
131+
115132 ##
116133 # Initializes the RDF/XML reader instance.
117134 #
@@ -196,7 +213,11 @@ def each_statement(&block)
196213 if rdf_nodes . size == 0
197214 # If none found, root element may be processed as an RDF Node
198215
199- ec = EvaluationContext . new ( base_uri , root , @graph ) do |prefix , value |
216+ # Extract RDF version from root
217+ @version = root . version
218+ add_debug ( root , "version: #{ @version . inspect } " )
219+
220+ ec = EvaluationContext . new ( base_uri , root , @graph , version : @version ) do |prefix , value |
200221 prefix ( prefix , value )
201222 end
202223
@@ -206,8 +227,13 @@ def each_statement(&block)
206227 log_fatal "node must be a proxy not a #{ node . class } " unless node . is_a? ( @implementation ::NodeProxy )
207228 # XXX Skip this element if it's contained within another rdf:RDF element
208229
209- # Extract base, lang and namespaces from parents to create proper evaluation context
210- ec = EvaluationContext . new ( base_uri , nil , @graph )
230+ # Extract RDF version from node
231+ # XXX potentially, one node is processed with version "1.2" and others are parsed without a version.
232+ @version = node . version
233+ add_debug ( root , "version: #{ @version . inspect } " )
234+
235+ # Extract base, lang, direction, version and namespaces from parents to create proper evaluation context
236+ ec = EvaluationContext . new ( base_uri , nil , @graph , version : @version )
211237 ec . extract_from_ancestors ( node ) do |prefix , value |
212238 prefix ( prefix , value )
213239 end
@@ -322,7 +348,11 @@ def nodeElement(el, ec)
322348 elsif is_propertyAttr? ( attr )
323349 # Attributes not RDF.type
324350 predicate = attr . uri
325- lit = RDF ::Literal . new ( attr . value , language : ec . language , validate : validate? , canonicalize : canonicalize? )
351+ lit = RDF ::Literal . new ( attr . value ,
352+ language : ec . language ,
353+ direction : ( ec . direction if ec . language ) ,
354+ validate : validate? ,
355+ canonicalize : canonicalize? )
326356 add_triple ( attr , subject , predicate , lit )
327357 end
328358 end
@@ -391,6 +421,8 @@ def nodeElement(el, ec)
391421 when "nodeID" then nodeID = attr . value
392422 else attrs [ attr ] = attr . value
393423 end
424+ elsif attr . namespace . href == RDF ::ITS . to_s
425+ # No production. Direction already extracted
394426 else
395427 attrs [ attr ] = attr . value
396428 end
@@ -430,6 +462,7 @@ def nodeElement(el, ec)
430462 literal_opts [ :datatype ] = uri ( datatype )
431463 else
432464 literal_opts [ :language ] = child_ec . language
465+ literal_opts [ :direction ] = ( child_ec . direction if child_ec . language )
433466 end
434467 literal = RDF ::Literal . new ( child . inner_text , **literal_opts )
435468 add_triple ( child , subject , predicate , literal )
@@ -527,7 +560,7 @@ def nodeElement(el, ec)
527560
528561 if attrs . empty? && resourceAttr . nil? && nodeID . nil?
529562
530- literal = RDF ::Literal . new ( "" , language : ec . language )
563+ literal = RDF ::Literal . new ( "" , language : ec . language , direction : ec . direction )
531564 add_triple ( child , subject , predicate , literal )
532565
533566 # Reification
@@ -552,7 +585,7 @@ def nodeElement(el, ec)
552585 next unless is_propertyAttr? ( attr )
553586
554587 # Attributes not in RDF.type
555- lit = RDF ::Literal . new ( val , language : child_ec . language )
588+ lit = RDF ::Literal . new ( val , language : child_ec . language , direction : child_ec . direction )
556589 add_triple ( child , resource , attr . uri , lit )
557590 end
558591 end
0 commit comments