rdf-rdfxml 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +2 -0
- data/{History.txt → History.rdoc} +21 -0
- data/README.rdoc +11 -12
- data/Rakefile +11 -19
- data/VERSION +1 -1
- data/lib/rdf/rdfxml.rb +3 -2
- data/lib/rdf/rdfxml/patches/literal_hacks.rb +15 -17
- data/lib/rdf/rdfxml/reader.rb +115 -79
- data/lib/rdf/rdfxml/version.rb +4 -7
- data/lib/rdf/rdfxml/writer.rb +239 -190
- data/rdf-rdfxml.gemspec +14 -20
- data/script/parse +16 -10
- data/script/tc +10 -9
- data/spec/graph_spec.rb +0 -16
- data/spec/literal_spec.rb +2 -3
- data/spec/rdf_helper.rb +6 -6
- data/spec/reader_spec.rb +17 -17
- data/spec/spec_helper.rb +11 -4
- data/spec/writer_spec.rb +384 -331
- metadata +22 -18
- data/lib/rdf/rdfxml/patches/qname_hacks.rb +0 -57
- data/lib/rdf/rdfxml/patches/seq.rb +0 -34
- data/lib/rdf/rdfxml/patches/uri_hacks.rb +0 -24
- data/spec/uri_spec.rb +0 -115
data/.yardopts
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
=== 0.3.0
|
2
|
+
* RDF.rb 0.3.0 compatibility updates
|
3
|
+
* Remove literal_normalization and qname_hacks, add back uri_hacks (until 0.3.0)
|
4
|
+
* Use nil for default namespace
|
5
|
+
* In Writer
|
6
|
+
* Use only :prefixes for creating QNames.
|
7
|
+
* Add :standard_prefixes and :default_namespace options.
|
8
|
+
* Improve Writer#to_qname.
|
9
|
+
* Don't try to translate rdf:_1 to rdf:li due to complex corner cases.
|
10
|
+
* Fix problems with XMLLiteral, rdf:type and rdf:nodeID serialization.
|
11
|
+
* In Reader
|
12
|
+
* URI canonicalization and validation.
|
13
|
+
* Added :canonicalize, and :intern options.
|
14
|
+
* Change :strict option to :validate.
|
15
|
+
* Don't create unnecessary namespaces.
|
16
|
+
* Don't use regexp to substitute base URI in URI serialization.
|
17
|
+
* Collect prefixes when extracting mappings.
|
18
|
+
* Literal::XML
|
19
|
+
* Add all in-scope namespaces, not just those that seem to be used.
|
20
|
+
* RSpec 2 compatibility
|
21
|
+
|
1
22
|
=== 0.2.3
|
2
23
|
* Fixed QName generation in Writer based on RDF/XML Processing recommendations
|
3
24
|
|
data/README.rdoc
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
RDF/XML parser for RDF.rb.
|
4
4
|
|
5
|
-
== DESCRIPTION
|
5
|
+
== DESCRIPTION
|
6
6
|
|
7
7
|
RDF::RDFXML is an RDF/XML reader/writer for Ruby using the RDF.rb library suite.
|
8
8
|
|
9
|
-
== FEATURES
|
10
|
-
RDF::RDFXML parses RDF/XML into statements or triples.
|
9
|
+
== FEATURES
|
10
|
+
RDF::RDFXML parses RDF/XML into statements or triples and serializes triples, statements or graphs.
|
11
11
|
|
12
|
-
* Fully compliant RDF/XML parser.
|
12
|
+
* Fully compliant RDF/XML parser and serializer.
|
13
13
|
|
14
14
|
Install with 'gem install rdf-rdfxml'
|
15
15
|
|
@@ -23,7 +23,7 @@ Instantiate a parser and parse source, specifying type and base-URL
|
|
23
23
|
end
|
24
24
|
|
25
25
|
== Dependencies
|
26
|
-
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.
|
26
|
+
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.3.0)
|
27
27
|
* [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.3.3)
|
28
28
|
|
29
29
|
== TODO
|
@@ -31,20 +31,20 @@ Instantiate a parser and parse source, specifying type and base-URL
|
|
31
31
|
* Consider a SAX-based parser for improved performance
|
32
32
|
* Add generic RDF/XML Writer
|
33
33
|
|
34
|
-
== Resources
|
34
|
+
== Resources
|
35
35
|
* Distiller[http://kellogg-assoc/distiller]
|
36
36
|
* RDoc[http://rdoc.info/projects/gkellogg/rdf-rdfxml]
|
37
37
|
* History[http://github.com/gkellogg/rdf-rdfxml/blob/master/History.txt]
|
38
38
|
* "XHTML+RDFXML 1.1 Core"[http://www.w3.org/TR/2010/WD-xhtml-rdfa-20100422/]
|
39
39
|
* "RDF Tests"[http://www.w3.org/2000/10/rdf-tests/rdfcore/allTestCases.html]
|
40
40
|
|
41
|
-
== AUTHOR
|
41
|
+
== AUTHOR
|
42
42
|
* Gregg Kellogg <gregg@kellogg-assoc.com>
|
43
43
|
|
44
|
-
== CONTRIBUTORS
|
44
|
+
== CONTRIBUTORS
|
45
45
|
* Nicholas Humfrey <nicholas.humfrey@bbc.co.uk>
|
46
46
|
|
47
|
-
== LICENSE
|
47
|
+
== LICENSE
|
48
48
|
|
49
49
|
(The MIT License)
|
50
50
|
|
@@ -72,7 +72,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
72
72
|
== FEEDBACK
|
73
73
|
|
74
74
|
* gregg@kellogg-assoc.com
|
75
|
-
* rubygems.org/rdf-rdfxml
|
76
|
-
* github.com/gkellogg/rdf-rdfxml
|
77
|
-
* gkellogg.lighthouseapp.com for bug reports
|
75
|
+
* http://rubygems.org/rdf-rdfxml
|
76
|
+
* http://github.com/gkellogg/rdf-rdfxml
|
78
77
|
* public-rdf-ruby mailing list on w3.org
|
data/Rakefile
CHANGED
@@ -7,43 +7,35 @@ begin
|
|
7
7
|
Jeweler::Tasks.new do |gemspec|
|
8
8
|
gemspec.name = "rdf-rdfxml"
|
9
9
|
gemspec.summary = "RDF/XML reader/writer for RDF.rb."
|
10
|
-
gemspec.description =
|
11
|
-
RDF::RDFXML is an RDF/XML reader and writer for Ruby using the RDF.rb library suite.
|
12
|
-
DESCRIPTION
|
10
|
+
gemspec.description = %q(RDF::RDFXML is an RDF/XML reader and writer for Ruby using the RDF.rb library suite.)
|
13
11
|
gemspec.email = "gregg@kellogg-assoc.com"
|
14
12
|
gemspec.homepage = "http://github.com/gkellogg/rdf-rdfxml"
|
15
13
|
gemspec.authors = ["Gregg Kellogg"]
|
16
|
-
gemspec.add_dependency('rdf', '>= 0.
|
14
|
+
gemspec.add_dependency('rdf', '>= 0.3.0')
|
17
15
|
gemspec.add_dependency('nokogiri', '>= 1.3.3')
|
18
|
-
gemspec.add_development_dependency('rspec')
|
19
|
-
gemspec.add_development_dependency('rdf-spec'
|
16
|
+
gemspec.add_development_dependency('rspec', '>= 2.1.0')
|
17
|
+
gemspec.add_development_dependency('rdf-spec')
|
20
18
|
gemspec.add_development_dependency('rdf-isomorphic')
|
21
19
|
gemspec.add_development_dependency('yard')
|
22
|
-
gemspec.extra_rdoc_files = %w(README.rdoc History.
|
20
|
+
gemspec.extra_rdoc_files = %w(README.rdoc History.rdoc AUTHORS CONTRIBUTORS)
|
23
21
|
end
|
24
22
|
Jeweler::GemcutterTasks.new
|
25
23
|
rescue LoadError
|
26
24
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
27
25
|
end
|
28
26
|
|
29
|
-
require '
|
30
|
-
|
31
|
-
spec.libs << 'lib' << 'spec'
|
32
|
-
spec.spec_files = FileList['spec/*_spec.rb']
|
33
|
-
end
|
27
|
+
require 'rspec/core/rake_task'
|
28
|
+
RSpec::Core::RakeTask.new(:spec)
|
34
29
|
|
35
30
|
desc "Run specs through RCov"
|
36
|
-
|
37
|
-
spec.libs << 'lib' << 'spec'
|
38
|
-
spec.pattern = 'spec/*_spec.rb'
|
31
|
+
RSpec::Core::RakeTask.new("spec:rcov") do |spec|
|
39
32
|
spec.rcov = true
|
33
|
+
spec.rcov_opts = %q[--exclude "spec"]
|
40
34
|
end
|
41
35
|
|
42
36
|
desc "Generate HTML report specs"
|
43
|
-
|
44
|
-
spec.
|
45
|
-
spec.spec_files = FileList['spec/*_spec.rb']
|
46
|
-
spec.spec_opts = ["--format", "html:doc/spec.html"]
|
37
|
+
RSpec::Core::RakeTask.new("doc:spec") do |spec|
|
38
|
+
spec.rspec_opts = ["--format", "html", "-o", "doc/spec.html"]
|
47
39
|
end
|
48
40
|
|
49
41
|
YARD::Rake::YardocTask.new do |t|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/rdf/rdfxml.rb
CHANGED
@@ -25,11 +25,12 @@ module RDF
|
|
25
25
|
require 'rdf/rdfxml/patches/array_hacks'
|
26
26
|
require 'rdf/rdfxml/patches/literal_hacks'
|
27
27
|
require 'rdf/rdfxml/patches/nokogiri_hacks'
|
28
|
-
require 'rdf/rdfxml/patches/qname_hacks'
|
29
|
-
require 'rdf/rdfxml/patches/uri_hacks'
|
30
28
|
autoload :Reader, 'rdf/rdfxml/reader'
|
31
29
|
autoload :Writer, 'rdf/rdfxml/writer'
|
32
30
|
autoload :VERSION, 'rdf/rdfxml/version'
|
33
31
|
autoload :XML, 'rdf/rdfxml/vocab'
|
32
|
+
|
33
|
+
def self.debug?; @debug; end
|
34
|
+
def self.debug=(value); @debug = value; end
|
34
35
|
end
|
35
36
|
end
|
@@ -20,7 +20,7 @@ module RDF; class Literal
|
|
20
20
|
##
|
21
21
|
# @param [Object] value
|
22
22
|
# @option options [String] :lexical (nil)
|
23
|
-
# @option options [Hash] :namespaces ({}) Use
|
23
|
+
# @option options [Hash] :namespaces ({}) Use "" to declare default namespace
|
24
24
|
# @option options [Symbol] :language (nil)
|
25
25
|
# @option options [:nokogiri, :libxml, or :rexml] :library
|
26
26
|
def initialize(value, options = {})
|
@@ -68,17 +68,15 @@ module RDF; class Literal
|
|
68
68
|
def parse_value(value, options)
|
69
69
|
ns_hash = {}
|
70
70
|
options[:namespaces].each_pair do |prefix, uri|
|
71
|
-
prefix = prefix
|
71
|
+
prefix = prefix.to_s
|
72
72
|
attr = prefix.empty? ? "xmlns" : "xmlns:#{prefix}"
|
73
73
|
ns_hash[attr] = uri.to_s
|
74
74
|
end
|
75
|
-
ns_strs = []
|
76
|
-
ns_hash.each_pair {|a, u| ns_strs << "#{a}=\"#{u}\""}
|
77
75
|
|
78
76
|
case @library
|
79
|
-
when :nokogiri then parse_value_nokogiri(value,
|
80
|
-
when :libxml then parse_value_libxml(value,
|
81
|
-
when :rexml then parse_value_rexml(value,
|
77
|
+
when :nokogiri then parse_value_nokogiri(value, ns_hash, options)
|
78
|
+
when :libxml then parse_value_libxml(value, ns_hash, options)
|
79
|
+
when :rexml then parse_value_rexml(value, ns_hash, options)
|
82
80
|
else value.to_s
|
83
81
|
end
|
84
82
|
end
|
@@ -99,10 +97,12 @@ module RDF; class Literal
|
|
99
97
|
# to the required element, and does not properly order either namespaces or attributes.
|
100
98
|
#
|
101
99
|
# An open-issue in Nokogiri is to add support for C14N from the underlying libxml2 libraries.
|
102
|
-
def parse_value_nokogiri(value,
|
100
|
+
def parse_value_nokogiri(value, ns_hash, options)
|
103
101
|
elements = if value.is_a?(Nokogiri::XML::NodeSet)
|
104
102
|
value
|
105
103
|
else
|
104
|
+
ns_strs = []
|
105
|
+
ns_hash.each_pair {|a, u| ns_strs << "#{a}=\"#{u}\""}
|
106
106
|
# Add inherited namespaces to created root element so that they're inherited to sub-elements
|
107
107
|
Nokogiri::XML::Document.parse("<foo #{ns_strs.join(" ")}>#{value.to_s}</foo>").root.children
|
108
108
|
end
|
@@ -110,17 +110,15 @@ module RDF; class Literal
|
|
110
110
|
elements.map do |c|
|
111
111
|
if c.is_a?(Nokogiri::XML::Element)
|
112
112
|
c = Nokogiri::XML.parse(c.dup.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)).root
|
113
|
-
# Gather namespaces from self and decendant nodes
|
114
|
-
c.traverse do |n|
|
115
|
-
ns = n.namespace
|
116
|
-
next unless ns
|
117
|
-
prefix = ns.prefix ? "xmlns:#{ns.prefix}" : "xmlns"
|
118
|
-
c[prefix] = ns.href.to_s unless c.namespaces[prefix]
|
119
|
-
end
|
120
113
|
|
114
|
+
# Apply defined namespaces
|
115
|
+
ns_hash.each_pair do |prefix, href|
|
116
|
+
c[prefix] = href unless c.namespaces[prefix]
|
117
|
+
end
|
118
|
+
|
121
119
|
# Add language
|
122
|
-
if language && c["lang"].to_s.empty?
|
123
|
-
c["xml:lang"] = language.to_s
|
120
|
+
if options[:language] && c["lang"].to_s.empty?
|
121
|
+
c["xml:lang"] = options[:language].to_s
|
124
122
|
end
|
125
123
|
end
|
126
124
|
c
|
data/lib/rdf/rdfxml/reader.rb
CHANGED
@@ -4,6 +4,8 @@ module RDF::RDFXML
|
|
4
4
|
##
|
5
5
|
# An RDF/XML parser in Ruby
|
6
6
|
#
|
7
|
+
# Based on RDF/XML Syntax Specification: http://www.w3.org/TR/REC-rdf-syntax/
|
8
|
+
#
|
7
9
|
# @author [Gregg Kellogg](http://kellogg-assoc.com/)
|
8
10
|
class Reader < RDF::Reader
|
9
11
|
format Format
|
@@ -33,7 +35,7 @@ module RDF::RDFXML
|
|
33
35
|
attr :graph, true
|
34
36
|
attr :li_counter, true
|
35
37
|
|
36
|
-
def initialize(base, element, graph)
|
38
|
+
def initialize(base, element, graph, &cb)
|
37
39
|
# Initialize the evaluation context, [5.1]
|
38
40
|
self.base = RDF::URI.intern(base)
|
39
41
|
@uri_mappings = {}
|
@@ -41,51 +43,52 @@ module RDF::RDFXML
|
|
41
43
|
@graph = graph
|
42
44
|
@li_counter = 0
|
43
45
|
|
44
|
-
extract_from_element(element) if element
|
46
|
+
extract_from_element(element, &cb) if element
|
45
47
|
end
|
46
48
|
|
47
49
|
# Clone existing evaluation context adding information from element
|
48
|
-
def clone(element, options = {})
|
50
|
+
def clone(element, options = {}, &cb)
|
49
51
|
new_ec = EvaluationContext.new(@base, nil, @graph)
|
50
52
|
new_ec.uri_mappings = self.uri_mappings.clone
|
51
53
|
new_ec.language = self.language
|
52
54
|
|
53
|
-
new_ec.extract_from_element(element) if element
|
55
|
+
new_ec.extract_from_element(element, &cb) if element
|
54
56
|
|
55
57
|
options.each_pair {|k, v| new_ec.send("#{k}=", v)}
|
56
58
|
new_ec
|
57
59
|
end
|
58
60
|
|
59
61
|
# Extract Evaluation Context from an element by looking at ancestors recurively
|
60
|
-
def extract_from_ancestors(el)
|
62
|
+
def extract_from_ancestors(el, &cb)
|
61
63
|
ancestors = el.ancestors
|
62
64
|
while ancestors.length > 0
|
63
65
|
a = ancestors.pop
|
64
66
|
next unless a.element?
|
65
|
-
extract_from_element(a)
|
67
|
+
extract_from_element(a, &cb)
|
66
68
|
end
|
67
|
-
extract_from_element(el)
|
69
|
+
extract_from_element(el, &cb)
|
68
70
|
end
|
69
71
|
|
70
72
|
# Extract Evaluation Context from an element
|
71
|
-
def extract_from_element(el)
|
73
|
+
def extract_from_element(el, &cb)
|
72
74
|
b = el.attribute_with_ns("base", RDF::XML.to_s)
|
73
75
|
lang = el.attribute_with_ns("lang", RDF::XML.to_s)
|
74
76
|
self.base = self.base.join(b) if b
|
75
77
|
self.language = lang if lang
|
76
|
-
self.uri_mappings.merge!(extract_mappings(el))
|
78
|
+
self.uri_mappings.merge!(extract_mappings(el, &cb))
|
77
79
|
end
|
78
80
|
|
79
81
|
# Extract the XMLNS mappings from an element
|
80
|
-
def extract_mappings(element)
|
82
|
+
def extract_mappings(element, &cb)
|
81
83
|
mappings = {}
|
82
84
|
|
83
85
|
# look for xmlns
|
84
86
|
element.namespaces.each do |attr_name,attr_value|
|
85
|
-
abbr,
|
87
|
+
abbr, prefix = attr_name.to_s.split(":")
|
86
88
|
if abbr == "xmlns"
|
87
89
|
attr_value = self.base.to_s + attr_value if attr_value.match(/^\#/)
|
88
|
-
mappings[
|
90
|
+
mappings[prefix] = attr_value
|
91
|
+
cb.call(prefix, attr_value) if block_given?
|
89
92
|
end
|
90
93
|
end
|
91
94
|
mappings
|
@@ -99,8 +102,9 @@ module RDF::RDFXML
|
|
99
102
|
|
100
103
|
# Set XML base. Ignore any fragment
|
101
104
|
def base=(b)
|
102
|
-
|
103
|
-
|
105
|
+
base = Addressable::URI.parse(b)
|
106
|
+
base.fragment = nil
|
107
|
+
@base = RDF::URI.intern(base)
|
104
108
|
end
|
105
109
|
|
106
110
|
def inspect
|
@@ -113,29 +117,41 @@ module RDF::RDFXML
|
|
113
117
|
##
|
114
118
|
# Initializes the RDF/XML reader instance.
|
115
119
|
#
|
116
|
-
# @param [IO, File, String]
|
117
|
-
#
|
118
|
-
# @
|
119
|
-
#
|
120
|
+
# @param [Nokogiri::XML::Document, IO, File, String] input
|
121
|
+
# the input stream to read
|
122
|
+
# @param [Hash{Symbol => Object}] options
|
123
|
+
# any additional options
|
124
|
+
# @option options [Encoding] :encoding (Encoding::UTF_8)
|
125
|
+
# the encoding of the input stream (Ruby 1.9+)
|
126
|
+
# @option options [Boolean] :validate (false)
|
127
|
+
# whether to validate the parsed statements and values
|
128
|
+
# @option options [Boolean] :canonicalize (false)
|
129
|
+
# whether to canonicalize parsed literals
|
130
|
+
# @option options [Boolean] :intern (true)
|
131
|
+
# whether to intern all parsed URIs
|
132
|
+
# @option options [Hash] :prefixes (Hash.new)
|
133
|
+
# the prefix mappings to use (not supported by all readers)
|
134
|
+
# @option options [#to_s] :base_uri (nil)
|
135
|
+
# the base URI to use when resolving relative URIs
|
136
|
+
# @option options [Array] :debug
|
137
|
+
# Array to place debug messages
|
120
138
|
# @return [reader]
|
121
|
-
# @yield [reader]
|
122
|
-
# @yieldparam
|
123
|
-
# @
|
139
|
+
# @yield [reader] `self`
|
140
|
+
# @yieldparam [RDF::Reader] reader
|
141
|
+
# @yieldreturn [void] ignored
|
142
|
+
# @raise [Error]:: Raises RDF::ReaderError if _validate_
|
124
143
|
def initialize(input = $stdin, options = {}, &block)
|
125
144
|
super do
|
126
145
|
@debug = options[:debug]
|
127
|
-
@
|
128
|
-
@base_uri = RDF::URI.intern(options[:base_uri])
|
146
|
+
@base_uri = uri(options[:base_uri]) if options[:base_uri]
|
129
147
|
|
130
|
-
@id_mapping = Hash.new
|
131
|
-
|
132
148
|
@doc = case input
|
133
149
|
when Nokogiri::XML::Document then input
|
134
150
|
else Nokogiri::XML.parse(input, @base_uri.to_s)
|
135
151
|
end
|
136
152
|
|
137
|
-
raise RDF::ReaderError, "Synax errors:\n#{@doc.errors}" if !@doc.errors.empty? &&
|
138
|
-
raise RDF::ReaderError, "Empty document" if (@doc.nil? || @doc.root.nil?) &&
|
153
|
+
raise RDF::ReaderError, "Synax errors:\n#{@doc.errors}" if !@doc.errors.empty? && validate?
|
154
|
+
raise RDF::ReaderError, "Empty document" if (@doc.nil? || @doc.root.nil?) && validate?
|
139
155
|
|
140
156
|
block.call(self) if block_given?
|
141
157
|
end
|
@@ -165,18 +181,25 @@ module RDF::RDFXML
|
|
165
181
|
if rdf_nodes.length == 0
|
166
182
|
# If none found, root element may be processed as an RDF Node
|
167
183
|
|
168
|
-
ec = EvaluationContext.new(@base_uri, root, @graph)
|
184
|
+
ec = EvaluationContext.new(@base_uri, root, @graph) do |prefix, value|
|
185
|
+
prefix(prefix, value)
|
186
|
+
end
|
187
|
+
|
169
188
|
nodeElement(root, ec)
|
170
189
|
else
|
171
190
|
rdf_nodes.each do |node|
|
172
191
|
# XXX Skip this element if it's contained within another rdf:RDF element
|
173
192
|
|
174
193
|
# Extract base, lang and namespaces from parents to create proper evaluation context
|
175
|
-
ec = EvaluationContext.new(@base_uri, nil, @graph)
|
194
|
+
ec = EvaluationContext.new(@base_uri, nil, @graph) do |prefix, value|
|
195
|
+
prefix(prefix, value)
|
196
|
+
end
|
176
197
|
ec.extract_from_ancestors(node)
|
177
198
|
node.children.each {|el|
|
178
199
|
next unless el.elem?
|
179
|
-
new_ec = ec.clone(el)
|
200
|
+
new_ec = ec.clone(el) do |prefix, value|
|
201
|
+
prefix(prefix, value)
|
202
|
+
end
|
180
203
|
nodeElement(el, new_ec)
|
181
204
|
}
|
182
205
|
end
|
@@ -218,7 +241,7 @@ module RDF::RDFXML
|
|
218
241
|
# @param [XML Node, any] node:: XML Node or string for showing context
|
219
242
|
# @param [String] message::
|
220
243
|
def add_debug(node, message)
|
221
|
-
puts "#{node_path(node)}: #{message}" if
|
244
|
+
puts "#{node_path(node)}: #{message}" if ::RDF::RDFXML::debug?
|
222
245
|
@debug << "#{node_path(node)}: #{message}" if @debug.is_a?(Array)
|
223
246
|
end
|
224
247
|
|
@@ -229,7 +252,7 @@ module RDF::RDFXML
|
|
229
252
|
# @param [URI] predicate:: the predicate of the statement
|
230
253
|
# @param [URI, BNode, Literal] object:: the object of the statement
|
231
254
|
# @return [Statement]:: Added statement
|
232
|
-
# @raise [RDF::ReaderError]:: Checks parameter types and raises if they are incorrect if
|
255
|
+
# @raise [RDF::ReaderError]:: Checks parameter types and raises if they are incorrect if validating.
|
233
256
|
def add_triple(node, subject, predicate, object)
|
234
257
|
statement = RDF::Statement.new(subject, predicate, object)
|
235
258
|
add_debug(node, "statement: #{statement}")
|
@@ -241,7 +264,7 @@ module RDF::RDFXML
|
|
241
264
|
# @param [XML Element] el:: XMl Element to parse
|
242
265
|
# @param [EvaluationContext] ec:: Evaluation context
|
243
266
|
# @return [RDF::URI] subject:: The subject found for the node
|
244
|
-
# @raise [RDF::ReaderError]:: Raises Exception if
|
267
|
+
# @raise [RDF::ReaderError]:: Raises Exception if validating
|
245
268
|
def nodeElement(el, ec)
|
246
269
|
# subject
|
247
270
|
subject = ec.subject || parse_subject(el, ec)
|
@@ -266,7 +289,7 @@ module RDF::RDFXML
|
|
266
289
|
elsif is_propertyAttr?(attr)
|
267
290
|
# Attributes not RDF.type
|
268
291
|
predicate = attr.uri
|
269
|
-
lit = RDF::Literal.new(attr.value, :language => ec.language)
|
292
|
+
lit = RDF::Literal.new(attr.value, :language => ec.language, :validate => validate?, :canonicalize => canonicalize?)
|
270
293
|
add_triple(attr, subject, predicate, lit)
|
271
294
|
end
|
272
295
|
end
|
@@ -275,7 +298,9 @@ module RDF::RDFXML
|
|
275
298
|
li_counter = 0 # this will increase for each li we iterate through
|
276
299
|
el.children.each do |child|
|
277
300
|
next unless child.elem?
|
278
|
-
child_ec = ec.clone(child)
|
301
|
+
child_ec = ec.clone(child) do |prefix, value|
|
302
|
+
prefix(prefix, value)
|
303
|
+
end
|
279
304
|
predicate = child.uri
|
280
305
|
add_debug(child, "propertyElt, predicate: #{predicate}")
|
281
306
|
propertyElementURI_check(child)
|
@@ -330,13 +355,13 @@ module RDF::RDFXML
|
|
330
355
|
|
331
356
|
if nodeID && resourceAttr
|
332
357
|
add_debug(el, "Cannot have rdf:nodeID and rdf:resource.")
|
333
|
-
raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:resource.") if
|
358
|
+
raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:resource.") if validate?
|
334
359
|
end
|
335
360
|
|
336
361
|
# Apply character transformations
|
337
|
-
id = id_check(el, RDF::NTriples.
|
338
|
-
resourceAttr = RDF::NTriples.
|
339
|
-
nodeID = nodeID_check(el, RDF::NTriples.
|
362
|
+
id = id_check(el, RDF::NTriples.unescape(id), nil) if id
|
363
|
+
resourceAttr = RDF::NTriples.unescape(resourceAttr) if resourceAttr
|
364
|
+
nodeID = nodeID_check(el, RDF::NTriples.unescape(nodeID)) if nodeID
|
340
365
|
|
341
366
|
add_debug(child, "attrs: #{attrs.inspect}")
|
342
367
|
add_debug(child, "datatype: #{datatype}") if datatype
|
@@ -348,7 +373,9 @@ module RDF::RDFXML
|
|
348
373
|
if attrs.empty? && datatype.nil? && parseType.nil? && element_nodes.length == 1
|
349
374
|
# Production resourcePropertyElt
|
350
375
|
|
351
|
-
new_ec = child_ec.clone(nil)
|
376
|
+
new_ec = child_ec.clone(nil) do |prefix, value|
|
377
|
+
prefix(prefix, value)
|
378
|
+
end
|
352
379
|
new_node_element = element_nodes.first
|
353
380
|
add_debug(child, "resourcePropertyElt: #{node_path(new_node_element)}")
|
354
381
|
new_subject = nodeElement(new_node_element, new_ec)
|
@@ -357,9 +384,9 @@ module RDF::RDFXML
|
|
357
384
|
# Production literalPropertyElt
|
358
385
|
add_debug(child, "literalPropertyElt")
|
359
386
|
|
360
|
-
literal_opts = {}
|
387
|
+
literal_opts = {:validate => validate?, :canonicalize => canonicalize?}
|
361
388
|
if datatype
|
362
|
-
literal_opts[:datatype] =
|
389
|
+
literal_opts[:datatype] = uri(datatype)
|
363
390
|
else
|
364
391
|
literal_opts[:language] = child_ec.language
|
365
392
|
end
|
@@ -373,7 +400,7 @@ module RDF::RDFXML
|
|
373
400
|
unless attrs.empty?
|
374
401
|
warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
|
375
402
|
add_debug(child, warn)
|
376
|
-
raise RDF::ReaderError.new(warn) if
|
403
|
+
raise RDF::ReaderError.new(warn) if validate?
|
377
404
|
end
|
378
405
|
|
379
406
|
# For element e with possibly empty element content c.
|
@@ -396,7 +423,9 @@ module RDF::RDFXML
|
|
396
423
|
node.namespace = pt_attr.namespace
|
397
424
|
node.attributes.keys.each {|a| node.remove_attribute(a)}
|
398
425
|
node.node_name = "Description"
|
399
|
-
new_ec = child_ec.clone(nil, :subject => n)
|
426
|
+
new_ec = child_ec.clone(nil, :subject => n) do |prefix, value|
|
427
|
+
prefix(prefix, value)
|
428
|
+
end
|
400
429
|
nodeElement(node, new_ec)
|
401
430
|
elsif parseType == "Collection"
|
402
431
|
# Production parseTypeCollectionPropertyElt
|
@@ -405,7 +434,7 @@ module RDF::RDFXML
|
|
405
434
|
unless attrs.empty?
|
406
435
|
warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
|
407
436
|
add_debug(child, warn)
|
408
|
-
raise RDF::ReaderError.new(warn) if
|
437
|
+
raise RDF::ReaderError.new(warn) if validate?
|
409
438
|
end
|
410
439
|
|
411
440
|
# For element event e with possibly empty nodeElementList l. Set s:=list().
|
@@ -421,7 +450,9 @@ module RDF::RDFXML
|
|
421
450
|
o = s[i+1]
|
422
451
|
f = element_nodes[i]
|
423
452
|
|
424
|
-
new_ec = child_ec.clone(nil)
|
453
|
+
new_ec = child_ec.clone(nil) do |prefix, value|
|
454
|
+
prefix(prefix, value)
|
455
|
+
end
|
425
456
|
object = nodeElement(f, new_ec)
|
426
457
|
add_triple(child, n, RDF.first, object)
|
427
458
|
add_triple(child, n, RDF.rest, o ? o : RDF.nil)
|
@@ -433,13 +464,13 @@ module RDF::RDFXML
|
|
433
464
|
unless attrs.empty?
|
434
465
|
warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
|
435
466
|
add_debug(child, warn)
|
436
|
-
raise RDF::ReaderError.new(warn) if
|
467
|
+
raise RDF::ReaderError.new(warn) if validate?
|
437
468
|
end
|
438
469
|
|
439
470
|
if resourceAttr
|
440
471
|
warn = "illegal rdf:resource"
|
441
472
|
add_debug(child, warn)
|
442
|
-
raise RDF::ReaderError.new(warn) if
|
473
|
+
raise RDF::ReaderError.new(warn) if validate?
|
443
474
|
end
|
444
475
|
|
445
476
|
object = RDF::Literal.new(child.children, :datatype => RDF.XMLLiteral, :namespaces => child_ec.uri_mappings, :language => ec.language)
|
@@ -512,23 +543,23 @@ module RDF::RDFXML
|
|
512
543
|
|
513
544
|
if nodeID && about
|
514
545
|
add_debug(el, "Cannot have rdf:nodeID and rdf:about.")
|
515
|
-
raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:about.") if
|
546
|
+
raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:about.") if validate?
|
516
547
|
elsif nodeID && id
|
517
548
|
add_debug(el, "Cannot have rdf:nodeID and rdf:ID.")
|
518
|
-
raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:ID.") if
|
549
|
+
raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:ID.") if validate?
|
519
550
|
end
|
520
551
|
|
521
552
|
case
|
522
553
|
when id
|
523
|
-
add_debug(el, "parse_subject, id: '#{RDF::NTriples.
|
524
|
-
id_check(el, RDF::NTriples.
|
554
|
+
add_debug(el, "parse_subject, id: '#{RDF::NTriples.unescape(id.value)}'")
|
555
|
+
id_check(el, RDF::NTriples.unescape(id.value), ec.base) # Returns URI
|
525
556
|
when nodeID
|
526
557
|
# The value of rdf:nodeID must match the XML Name production
|
527
|
-
nodeID = nodeID_check(el, RDF::NTriples.
|
558
|
+
nodeID = nodeID_check(el, RDF::NTriples.unescape(nodeID.value))
|
528
559
|
add_debug(el, "parse_subject, nodeID: '#{nodeID}")
|
529
560
|
bnode(nodeID)
|
530
561
|
when about
|
531
|
-
about = RDF::NTriples.
|
562
|
+
about = RDF::NTriples.unescape(about.value)
|
532
563
|
add_debug(el, "parse_subject, about: '#{about}'")
|
533
564
|
ec.base.join(about)
|
534
565
|
else
|
@@ -539,28 +570,24 @@ module RDF::RDFXML
|
|
539
570
|
|
540
571
|
# ID attribute must be an NCName
|
541
572
|
def id_check(el, id, base)
|
542
|
-
|
543
|
-
# ID may only be specified once for the same URI
|
544
|
-
if base
|
545
|
-
# FIXME: Known bug in RDF::URI#join
|
546
|
-
uri = base.join("##{id}")
|
547
|
-
if @id_mapping[id] && @id_mapping[id] == uri
|
548
|
-
warn = "ID addtribute '#{id}' may only be defined once for the same URI"
|
549
|
-
add_debug(el, warn)
|
550
|
-
raise RDF::ReaderError.new(warn) if @strict
|
551
|
-
end
|
552
|
-
|
553
|
-
@id_mapping[id] = uri
|
554
|
-
# Returns URI, in this case
|
555
|
-
else
|
556
|
-
id
|
557
|
-
end
|
558
|
-
else
|
573
|
+
unless NC_REGEXP.match(id)
|
559
574
|
warn = "ID addtribute '#{id}' must be a NCName"
|
560
|
-
add_debug(el, "ID addtribute '#{id}' must be a NCName")
|
561
575
|
add_debug(el, warn)
|
562
|
-
raise RDF::ReaderError.new(warn) if
|
563
|
-
|
576
|
+
raise RDF::ReaderError.new(warn) if validate?
|
577
|
+
end
|
578
|
+
# ID may only be specified once for the same URI
|
579
|
+
if base
|
580
|
+
uri = uri(base, "##{id}")
|
581
|
+
if prefix(id) && RDF::URI(prefix(id)) == uri
|
582
|
+
warn = "ID addtribute '#{id}' may only be defined once for the same URI"
|
583
|
+
add_debug(el, warn)
|
584
|
+
raise RDF::ReaderError.new(warn) if validate?
|
585
|
+
end
|
586
|
+
|
587
|
+
RDF::URI(prefix(id, uri))
|
588
|
+
# Returns URI, in this case
|
589
|
+
else
|
590
|
+
id
|
564
591
|
end
|
565
592
|
end
|
566
593
|
|
@@ -571,7 +598,7 @@ module RDF::RDFXML
|
|
571
598
|
nodeID
|
572
599
|
else
|
573
600
|
add_debug(el, "nodeID addtribute '#{nodeID}' must be an XML Name")
|
574
|
-
raise RDF::ReaderError.new("nodeID addtribute '#{nodeID}' must be a NCName") if
|
601
|
+
raise RDF::ReaderError.new("nodeID addtribute '#{nodeID}' must be a NCName") if validate?
|
575
602
|
nil
|
576
603
|
end
|
577
604
|
end
|
@@ -581,7 +608,7 @@ module RDF::RDFXML
|
|
581
608
|
if ([RDF.Description.to_s, RDF.li.to_s] + OLD_TERMS).include?(attr.uri.to_s)
|
582
609
|
warn = "Invalid use of rdf:#{attr.name}"
|
583
610
|
add_debug(attr, warn)
|
584
|
-
raise RDF::ReaderError.new(warn) if
|
611
|
+
raise RDF::ReaderError.new(warn) if validate?
|
585
612
|
return false
|
586
613
|
end
|
587
614
|
!CORE_SYNTAX_TERMS.include?(attr.uri.to_s) && attr.namespace && attr.namespace.href != RDF::XML.to_s
|
@@ -592,7 +619,7 @@ module RDF::RDFXML
|
|
592
619
|
if (CORE_SYNTAX_TERMS + [RDF.li.to_s] + OLD_TERMS).include?(el.uri.to_s)
|
593
620
|
warn = "Invalid use of rdf:#{el.name}"
|
594
621
|
add_debug(el, warn)
|
595
|
-
raise RDF::ReaderError.new(warn) if
|
622
|
+
raise RDF::ReaderError.new(warn) if validate?
|
596
623
|
end
|
597
624
|
end
|
598
625
|
|
@@ -601,7 +628,7 @@ module RDF::RDFXML
|
|
601
628
|
if (CORE_SYNTAX_TERMS + [RDF.Description.to_s] + OLD_TERMS).include?(el.uri.to_s)
|
602
629
|
warn = "Invalid use of rdf:#{el.name}"
|
603
630
|
add_debug(el, warn)
|
604
|
-
raise RDF::ReaderError.new(warn) if
|
631
|
+
raise RDF::ReaderError.new(warn) if validate?
|
605
632
|
end
|
606
633
|
end
|
607
634
|
|
@@ -610,10 +637,19 @@ module RDF::RDFXML
|
|
610
637
|
el.attribute_nodes.each do |attr|
|
611
638
|
if OLD_TERMS.include?(attr.uri.to_s)
|
612
639
|
add_debug(el, "Obsolete attribute '#{attr.uri}'")
|
613
|
-
raise RDF::ReaderError.new("Obsolete attribute '#{attr.uri}'") if
|
640
|
+
raise RDF::ReaderError.new("Obsolete attribute '#{attr.uri}'") if validate?
|
614
641
|
end
|
615
642
|
end
|
616
643
|
end
|
617
644
|
|
645
|
+
def uri(value, append = nil)
|
646
|
+
value = RDF::URI.new(value)
|
647
|
+
value = value.join(append) if append
|
648
|
+
value.validate! if validate?
|
649
|
+
value.canonicalize! if canonicalize?
|
650
|
+
value = RDF::URI.intern(value) if intern?
|
651
|
+
value
|
652
|
+
end
|
653
|
+
|
618
654
|
end
|
619
655
|
end
|