rdf-rdfxml 0.0.1

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.
@@ -0,0 +1,10 @@
1
+ --title "RDF::RDFa - RDFa Support for RDF.rb"
2
+ --output-dir doc/yard
3
+ --protected
4
+ --no-private
5
+ --hide-void-return
6
+ --markup rdoc
7
+ --readme README.rdoc
8
+ -
9
+ AUTHORS
10
+ VERSION
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ * Gregg Kellogg <gregg@kellogg-assoc.com>
@@ -0,0 +1,2 @@
1
+ === 0.0.1
2
+ * First port from RdfContext version 0.5.4
@@ -0,0 +1,61 @@
1
+ = RDF::RDFa reader/writer
2
+
3
+ RDF/XML parser for RDF.rb.
4
+
5
+ == DESCRIPTION:
6
+
7
+ RDF::RDFXML is an RDF/XML parser for Ruby using the RDF.rb library suite.
8
+
9
+ == FEATURES:
10
+ RDF::RDFXML parses RDF/XML into statements or triples.
11
+
12
+ * Fully compliant RDF/XML parser.
13
+
14
+ Install with 'gem install rdf-rdfxml'
15
+
16
+ == Usage:
17
+ Instantiate a parser and parse source, specifying type and base-URL
18
+
19
+ RDF::RDFXML::Reader.open("etc/foaf.xml") do |reader|
20
+ reader.each_statement do |statement|
21
+ puts statement.inspect
22
+ end
23
+ end
24
+
25
+ == Resources:
26
+ * Distiller[http://kellogg-assoc/distiller]
27
+ * RDoc[http://rdoc.info/projects/gkellogg/rdf-rdfxml]
28
+ * History[http://github.com/gkellogg/rdf-rdfxml/blob/master/History.txt]
29
+
30
+ == LICENSE:
31
+
32
+ (The MIT License)
33
+
34
+ Copyright (c) 2009-2010 Gregg Kellogg
35
+
36
+ Permission is hereby granted, free of charge, to any person obtaining
37
+ a copy of this software and associated documentation files (the
38
+ 'Software'), to deal in the Software without restriction, including
39
+ without limitation the rights to use, copy, modify, merge, publish,
40
+ distribute, sublicense, and/or sell copies of the Software, and to
41
+ permit persons to whom the Software is furnished to do so, subject to
42
+ the following conditions:
43
+
44
+ The above copyright notice and this permission notice shall be
45
+ included in all copies or substantial portions of the Software.
46
+
47
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
48
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
50
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
51
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
52
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
53
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
54
+
55
+ == FEEDBACK
56
+
57
+ * gregg@kellogg-assoc.com
58
+ * rubygems.org/rdf-rdfxml
59
+ * github.com/gkellogg/rdf-rdfxml
60
+ * gkellogg.lighthouseapp.com for bug reports
61
+ * public-rdf-ruby mailing list on w3.org
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ gem 'jeweler'
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = "rdf-rdfxml"
8
+ gemspec.summary = "RDF/XML reader/writer for RDF.rb."
9
+ gemspec.description = <<-DESCRIPTION
10
+ RDF::RDFXML is an RDF/XML reader and writer for Ruby using the RDF.rb library suite.
11
+ DESCRIPTION
12
+ gemspec.email = "gregg@kellogg-assoc.com"
13
+ gemspec.homepage = "http://github.com/gkellogg/rdf-rdfxml"
14
+ gemspec.authors = ["Gregg Kellogg"]
15
+ gemspec.add_dependency('rdf', '>= 0.1.6')
16
+ gemspec.add_dependency('nokogiri', '>= 1.3.3')
17
+ gemspec.add_development_dependency('rspec')
18
+ gemspec.add_development_dependency('rdf-spec')
19
+ gemspec.add_development_dependency('activesupport', '>= 2.3.0')
20
+ gemspec.extra_rdoc_files = %w(README.rdoc History.txt AUTHORS)
21
+ end
22
+ Jeweler::GemcutterTasks.new
23
+ rescue LoadError
24
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
25
+ end
26
+
27
+ require 'spec/rake/spectask'
28
+ Spec::Rake::SpecTask.new(:spec) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.spec_files = FileList['spec/*_spec.rb']
31
+ end
32
+
33
+ desc "Run specs through RCov"
34
+ Spec::Rake::SpecTask.new("spec:rcov") do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ desc "Generate HTML report specs"
41
+ Spec::Rake::SpecTask.new("doc:spec") do |spec|
42
+ spec.libs << 'lib' << 'spec'
43
+ spec.spec_files = FileList['spec/*_spec.rb']
44
+ spec.spec_opts = ["--format", "html:doc/spec.html"]
45
+ end
46
+
47
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
4
+
5
+ require 'rubygems'
6
+ require 'rdf/rdfxml'
7
+
8
+ data = <<-EOF;
9
+ <?xml version="1.0" ?>
10
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
11
+ xmlns:ex="http://www.example.org/" xml:lang="en" xml:base="http://www.example.org/foo">
12
+ <ex:Thing rdf:about="http://example.org/joe" ex:name="bar">
13
+ <ex:belongsTo rdf:resource="http://tommorris.org/" />
14
+ <ex:sampleText rdf:datatype="http://www.w3.org/2001/XMLSchema#string">foo</ex:sampleText>
15
+ <ex:hadADodgyRelationshipWith>
16
+ <rdf:Description>
17
+ <ex:name>Tom</ex:name>
18
+ <ex:hadADodgyRelationshipWith>
19
+ <rdf:Description>
20
+ <ex:name>Rob</ex:name>
21
+ <ex:hadADodgyRelationshipWith>
22
+ <rdf:Description>
23
+ <ex:name>Mary</ex:name>
24
+ </rdf:Description>
25
+ </ex:hadADodgyRelationshipWith>
26
+ </rdf:Description>
27
+ </ex:hadADodgyRelationshipWith>
28
+ </rdf:Description>
29
+ </ex:hadADodgyRelationshipWith>
30
+ </ex:Thing>
31
+ </rdf:RDF>
32
+ EOF
33
+
34
+ RDF::RDFXML::Reader.new(data, :base_uri => 'http://example.org/example.xml') do |reader|
35
+ reader.each_statement do |statement|
36
+ statement.inspect!
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ require 'rdf'
3
+
4
+ module RDF
5
+ ##
6
+ # **`RDF::RDFXML`** is an RDF/XML plugin for RDF.rb.
7
+ #
8
+ # @example Requiring the `RDF::RDFXML` module
9
+ # require 'rdf/rdfxml'
10
+ #
11
+ # @example Parsing RDF statements from an XHTML+RDFa file
12
+ # RDF::RDFXML::Reader.open("etc/foaf.xml") do |reader|
13
+ # reader.each_statement do |statement|
14
+ # puts statement.inspect
15
+ # end
16
+ # end
17
+ #
18
+ # @see http://rdf.rubyforge.org/
19
+ # @see http://www.w3.org/TR/REC-rdf-syntax/
20
+ #
21
+ # @author [Gregg Kellogg](http://kellogg-assoc.com/)
22
+ module RDFa
23
+ require 'rdfxml/format'
24
+ require 'rdfxml/vocab'
25
+ autoload :Reader, 'rdf/rdfxml/reader'
26
+ autoload :VERSION, 'rdf/rdfxml/version'
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module RDF::RDFXML
2
+ ##
3
+ # RDFa format specification.
4
+ #
5
+ # @example Obtaining an RDFa format class
6
+ # RDF::Format.for(:rdfxml) #=> RDF::RDFXML::Format
7
+ # RDF::Format.for("etc/foaf.xml")
8
+ # RDF::Format.for(:file_name => "etc/foaf.xml")
9
+ # RDF::Format.for(:file_extension => "xml")
10
+ # RDF::Format.for(:file_extension => "rdf")
11
+ # RDF::Format.for(:content_type => "application/xml")
12
+ # RDF::Format.for(:content_type => "application/rdf+xml")
13
+ #
14
+ # @example Obtaining serialization format MIME types
15
+ # RDF::Format.content_types #=> {"application/rdf+xml" => [RDF::RDFXML::Format]}
16
+ #
17
+ # @example Obtaining serialization format file extension mappings
18
+ # RDF::Format.file_extensions #=> {:rdf => "application/rdf+xml"}
19
+ #
20
+ # @see http://www.w3.org/TR/rdf-testcases/#ntriples
21
+ class Format < RDF::Format
22
+ content_type 'application/xml', :extension => :xml
23
+ content_type 'application/rdf+xml', :extension => :rdf
24
+ content_encoding 'utf-8'
25
+
26
+ reader { RDF::RDFa::RDFXML }
27
+ writer { RDF::RDFa::RDFXML }
28
+ end
29
+ end
@@ -0,0 +1,583 @@
1
+ require 'nokogiri' # FIXME: Implement using different modules as in RDF::TriX
2
+
3
+ module RDF::RDFXML
4
+ ##
5
+ # An RDF/XML parser in Ruby
6
+ #
7
+ # @author [Gregg Kellogg](http://kellogg-assoc.com/)
8
+ class Reader < RDF::Reader
9
+ format Format
10
+
11
+ CORE_SYNTAX_TERMS = %w(RDF ID about parseType resource nodeID datatype).map {|n| "http://www.w3.org/1999/02/22-rdf-syntax-ns##{n}"}
12
+ OLD_TERMS = %w(aboutEach aboutEachPrefix bagID).map {|n| "http://www.w3.org/1999/02/22-rdf-syntax-ns##{n}"}
13
+
14
+ NC_REGEXP = Regexp.new(
15
+ %{^
16
+ (?!\\\\u0301) # &#x301; is a non-spacing acute accent.
17
+ # It is legal within an XML Name, but not as the first character.
18
+ ( [a-zA-Z_]
19
+ | \\\\u[0-9a-fA-F]
20
+ )
21
+ ( [0-9a-zA-Z_\.-]
22
+ | \\\\u([0-9a-fA-F]{4})
23
+ )*
24
+ $},
25
+ Regexp::EXTENDED)
26
+
27
+ XML_LITERAL = RDF['XMLLiteral']
28
+
29
+ # The Recursive Baggage
30
+ class EvaluationContext # :nodoc:
31
+ attr_reader :base
32
+ attr :subject, true
33
+ attr :uri_mappings, true
34
+ attr :language, true
35
+ attr :graph, true
36
+ attr :li_counter, true
37
+
38
+ def initialize(base, element, graph)
39
+ # Initialize the evaluation context, [5.1]
40
+ self.base = RDF::URI.new(base)
41
+ @uri_mappings = {}
42
+ @language = nil
43
+ @graph = graph
44
+ @li_counter = 0
45
+ @uri_mappings = {}
46
+
47
+ extract_from_element(element) if element
48
+ end
49
+
50
+ # Clone existing evaluation context adding information from element
51
+ def clone(element, options = {})
52
+ new_ec = EvaluationContext.new(@base, nil, @graph)
53
+ new_ec.uri_mappings = self.uri_mappings.clone
54
+ new_ec.language = self.language
55
+
56
+ new_ec.extract_from_element(element) if element
57
+
58
+ options.each_pair {|k, v| new_ec.send("#{k}=", v)}
59
+ new_ec
60
+ end
61
+
62
+ # Extract Evaluation Context from an element by looking at ancestors recurively
63
+ def extract_from_ancestors(el)
64
+ ancestors = el.ancestors
65
+ while ancestors.length > 0
66
+ a = ancestors.pop
67
+ next unless a.element?
68
+ extract_from_element(a)
69
+ end
70
+ extract_from_element(el)
71
+ end
72
+
73
+ # Extract Evaluation Context from an element
74
+ def extract_from_element(el)
75
+ b = el.attribute_with_ns("base", XML_NS.uri.to_s)
76
+ lang = el.attribute_with_ns("lang", XML_NS.uri.to_s)
77
+ self.base = self.base.join(b) if b
78
+ self.language = lang if lang
79
+ self.uri_mappings.merge!(extract_mappings(el))
80
+ end
81
+
82
+ # Extract the XMLNS mappings from an element
83
+ def extract_mappings(element)
84
+ mappings = {}
85
+
86
+ # look for xmlns
87
+ element.namespaces.each do |attr_name,attr_value|
88
+ abbr, suffix = attr_name.to_s.split(":")
89
+ if abbr == "xmlns"
90
+ attr_value = self.base.to_s + attr_value if attr_value.match(/^\#/)
91
+ mappings[suffix] = Namespace.new(attr_value, suffix)
92
+ @graph.bind(mappings[suffix])
93
+ end
94
+ end
95
+ mappings
96
+ end
97
+
98
+ # Produce the next list entry for this context
99
+ def li_next
100
+ @li_counter += 1
101
+ predicate = URIRef.new(RDF["_#{@li_counter}"])
102
+ end
103
+
104
+ # Set XML base. Ignore any fragment
105
+ def base=(b)
106
+ b = Addressable::URI.parse(b.to_s)
107
+ b.fragment = nil
108
+ @base = RDF::URI.new(b)
109
+ end
110
+
111
+ def inspect
112
+ v = %w(base subject language).map {|a| "#{a}='#{self.send(a).nil? ? 'nil' : self.send(a)}'"}
113
+ v << "uri_mappings[#{uri_mappings.keys.length}]"
114
+ v.join(",")
115
+ end
116
+ end
117
+
118
+ ##
119
+ # Initializes the RDF/XML reader instance.
120
+ #
121
+ # @param [IO, File, String]:: input
122
+ # @param [Hash{Symbol => Object}]:: options
123
+ # <em>options[:debug]</em>:: Array to place debug messages
124
+ # <em>options[:strict]</em>:: Raise Error if true, continue with lax parsing, otherwise
125
+ # <em>options[:base_uri]</em>:: Base URI to use for relative URIs.
126
+ # @yield [reader]
127
+ # @yieldparam [Reader] reader
128
+ # @raise [Error]:: Raises RDF::ReaderError if _strict_
129
+ def initialize(input = $stdin, options = {}, &block)
130
+ super do
131
+ @graph = RDF::Graph.new
132
+ @debug = options[:debug]
133
+ @strict = options[:strict]
134
+ @base_uri = options[:base_uri]
135
+ @base_uri = RDF::URI.parse(@base_uri) if @base_uri.is_a?(String)
136
+
137
+ @doc = case stream
138
+ when Nokogiri::XML::Document then stream
139
+ else Nokogiri::XML.parse(stream, uri.to_s)
140
+ end
141
+
142
+ raise RDF::ReaderError, "Empty document" if @doc.nil? && @strict
143
+ @callback = block
144
+
145
+ # Look for rdf:RDF elements and process each.
146
+ rdf_nodes = root.xpath("//rdf:RDF", RDF.prefix => RDF.uri.to_s)
147
+ if rdf_nodes.length == 0
148
+ # If none found, root element may be processed as an RDF Node
149
+
150
+ ec = EvaluationContext.new(@uri, root, @graph)
151
+ nodeElement(root, ec)
152
+ else
153
+ rdf_nodes.each do |node|
154
+ # XXX Skip this element if it's contained within another rdf:RDF element
155
+
156
+ # Extract base, lang and namespaces from parents to create proper evaluation context
157
+ ec = EvaluationContext.new(@uri, nil, @graph)
158
+ ec.extract_from_ancestors(node)
159
+ node.children.each {|el|
160
+ next unless el.elem?
161
+ new_ec = ec.clone(el)
162
+ nodeElement(el, new_ec)
163
+ }
164
+ end
165
+ end
166
+
167
+ block.call(self) if block_given?
168
+ end
169
+ end
170
+
171
+ private
172
+
173
+ # Figure out the document path, if it is a Nokogiri::XML::Element or Attribute
174
+ def node_path(node)
175
+ case node
176
+ when Nokogiri::XML::Element, Nokogiri::XML::Attr then "#{node_path(node.parent)}/#{node.name}"
177
+ when String then node
178
+ else ""
179
+ end
180
+ end
181
+
182
+ # Add debug event to debug array, if specified
183
+ #
184
+ # @param [XML Node, any] node:: XML Node or string for showing context
185
+ # @param [String] message::
186
+ def add_debug(node, message)
187
+ puts "#{node_path(node)}: #{message}" if $DEBUG
188
+ @debug << "#{node_path(node)}: #{message}" if @debug.is_a?(Array)
189
+ end
190
+
191
+ # add a statement, object can be literal or URI or bnode
192
+ #
193
+ # @param [Nokogiri::XML::Node, any] node:: XML Node or string for showing context
194
+ # @param [URI, BNode] subject:: the subject of the statement
195
+ # @param [URI] predicate:: the predicate of the statement
196
+ # @param [URI, BNode, Literal] object:: the object of the statement
197
+ # @return [Statement]:: Added statement
198
+ # @raise [RDF::ReaderError]:: Checks parameter types and raises if they are incorrect if parsing mode is _strict_.
199
+ def add_triple(node, subject, predicate, object)
200
+ statement = RDF::Statement.new(subject, predicate, object)
201
+ add_debug(node, "statement: #{statement}")
202
+ @graph << statement
203
+ statement
204
+ rescue RDF::ReaderError => e
205
+ add_debug(node, "add_triple raised #{e.class}: #{e.message}")
206
+ puts e.backtrace if $DEBUG
207
+ raise if @strict
208
+ end
209
+
210
+ # XML nodeElement production
211
+ #
212
+ # @param [XML Element] el:: XMl Element to parse
213
+ # @param [EvaluationContext] ec:: Evaluation context
214
+ # @return [RDF::URI] subject:: The subject found for the node
215
+ # @raise [RDF::ReaderError]:: Raises Exception if _strict_
216
+ def nodeElement(el, ec)
217
+ # subject
218
+ subject = ec.subject || parse_subject(el, ec)
219
+
220
+ add_debug(el, "nodeElement, ec: #{ec.inspect}")
221
+ add_debug(el, "nodeElement, el: #{el.uri}")
222
+ add_debug(el, "nodeElement, subject: #{subject.nil? ? 'nil' : subject.to_s}")
223
+
224
+ unless el.uri == RDF.Description.to_s
225
+ add_triple(el, subject, RDF.type, el.uri)
226
+ end
227
+
228
+ # produce triples for attributes
229
+ el.attribute_nodes.each do |attr|
230
+ add_debug(el, "propertyAttr: #{attr.uri}='#{attr.value}'")
231
+ if attr.uri == RDF.type
232
+ # If there is an attribute a in propertyAttr with a.URI == rdf:type
233
+ # then u:=uri(identifier:=resolve(a.string-value))
234
+ # and the following triple is added to the graph:
235
+ u = ec.base.join(attr.value)
236
+ add_triple(attr, subject, RDF.type, u)
237
+ elsif is_propertyAttr?(attr)
238
+ # Attributes not RDF.type
239
+ predicate = attr.uri
240
+ lit = Literal.untyped(attr.value, ec.language)
241
+ add_triple(attr, subject, predicate, lit)
242
+ end
243
+ end
244
+
245
+ # Handle the propertyEltList children events in document order
246
+ li_counter = 0 # this will increase for each li we iterate through
247
+ el.children.each do |child|
248
+ next unless child.elem?
249
+ child_ec = ec.clone(child)
250
+ predicate = child.uri
251
+ add_debug(child, "propertyElt, predicate: #{predicate}")
252
+ propertyElementURI_check(child)
253
+
254
+ # Determine the content type of this property element
255
+ text_nodes = child.children.select {|e| e.text? && !e.blank?}
256
+ element_nodes = child.children.select {|c| c.element? }
257
+ add_debug(child, "#{text_nodes.length} text nodes, #{element_nodes.length} element nodes")
258
+ if element_nodes.length > 1
259
+ element_nodes.each do |node|
260
+ add_debug(child, " node: #{node.to_s}")
261
+ end
262
+ end
263
+
264
+ # List expansion
265
+ predicate = ec.li_next if predicate == RDF.li
266
+
267
+ # Productions based on set of attributes
268
+
269
+ # All remaining reserved XML Names (See Name in XML 1.0) are now removed from the set.
270
+ # These are, all attribute information items in the set with property [prefix] beginning with xml
271
+ # (case independent comparison) and all attribute information items with [prefix] property having
272
+ # no value and which have [local name] beginning with xml (case independent comparison) are removed.
273
+ # Note that the [base URI] accessor is computed by XML Base before any xml:base attribute information item
274
+ # is deleted.
275
+ attrs = {}
276
+ id = datatype = parseType = resourceAttr = nodeID = nil
277
+
278
+ child.attribute_nodes.each do |attr|
279
+ if attr.namespace.to_s.empty?
280
+ # The support for a limited set of non-namespaced names is REQUIRED and intended to allow
281
+ # RDF/XML documents specified in [RDF-MS] to remain valid;
282
+ # new documents SHOULD NOT use these unqualified attributes and applications
283
+ # MAY choose to warn when the unqualified form is seen in a document.
284
+ add_debug(el, "Unqualified attribute '#{attr}'")
285
+ #attrs[attr.to_s] = attr.value unless attr.to_s.match?(/^xml/)
286
+ elsif attr.namespace.href == XML_NS.uri.to_s
287
+ # No production. Lang and base elements already extracted
288
+ elsif attr.namespace.href == RDF.uri.to_s
289
+ case attr.name
290
+ when "ID" then id = attr.value
291
+ when "datatype" then datatype = attr.value
292
+ when "parseType" then parseType = attr.value
293
+ when "resource" then resourceAttr = attr.value
294
+ when "nodeID" then nodeID = attr.value
295
+ else attrs[attr] = attr.value
296
+ end
297
+ else
298
+ attrs[attr] = attr.value
299
+ end
300
+ end
301
+
302
+ if nodeID && resourceAttr
303
+ add_debug(el, "Cannot have rdf:nodeID and rdf:resource.")
304
+ raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:resource.") if @strict
305
+ end
306
+
307
+ # Apply character transformations
308
+ id = id_check(el, id.rdf_escape, nil) if id
309
+ resourceAttr = resourceAttr.rdf_escape if resourceAttr
310
+ nodeID = nodeID_check(el, nodeID.rdf_escape) if nodeID
311
+
312
+ add_debug(child, "attrs: #{attrs.inspect}")
313
+ add_debug(child, "datatype: #{datatype}") if datatype
314
+ add_debug(child, "parseType: #{parseType}") if parseType
315
+ add_debug(child, "resource: #{resourceAttr}") if resourceAttr
316
+ add_debug(child, "nodeID: #{nodeID}") if nodeID
317
+ add_debug(child, "id: #{id}") if id
318
+
319
+ if attrs.empty? && datatype.nil? && parseType.nil? && element_nodes.length == 1
320
+ # Production resourcePropertyElt
321
+
322
+ new_ec = child_ec.clone(nil)
323
+ new_node_element = element_nodes.first
324
+ add_debug(child, "resourcePropertyElt: #{node_path(new_node_element)}")
325
+ new_subject = nodeElement(new_node_element, new_ec)
326
+ add_triple(child, subject, predicate, new_subject)
327
+ elsif attrs.empty? && parseType.nil? && element_nodes.length == 0 && text_nodes.length > 0
328
+ # Production literalPropertyElt
329
+ add_debug(child, "literalPropertyElt")
330
+
331
+ literal = RDF::Literal.new(child.inner_html, :datatype => datatype, :language => child_ec.language)
332
+ add_triple(child, subject, predicate, literal)
333
+ reify(id, child, subject, predicate, literal, ec) if id
334
+ elsif parseType == "Resource"
335
+ # Production parseTypeResourcePropertyElt
336
+ add_debug(child, "parseTypeResourcePropertyElt")
337
+
338
+ unless attrs.empty?
339
+ warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
340
+ add_debug(child, warn)
341
+ raise RDF::ReaderError.new(warn) if @strict
342
+ end
343
+
344
+ # For element e with possibly empty element content c.
345
+ n = BNode.new
346
+ add_triple(child, subject, predicate, n)
347
+
348
+ # Reification
349
+ reify(id, child, subject, predicate, n, child_ec) if id
350
+
351
+ # If the element content c is not empty, then use event n to create a new sequence of events as follows:
352
+ #
353
+ # start-element(URI := rdf:Description,
354
+ # subject := n,
355
+ # attributes := set())
356
+ # c
357
+ # end-element()
358
+ add_debug(child, "compose new sequence with rdf:Description")
359
+ node = child.clone
360
+ pt_attr = node.attribute("parseType")
361
+ node.namespace = pt_attr.namespace
362
+ node.attributes.keys.each {|a| node.remove_attribute(a)}
363
+ node.node_name = "Description"
364
+ new_ec = child_ec.clone(nil, :subject => n)
365
+ nodeElement(node, new_ec)
366
+ elsif parseType == "Collection"
367
+ # Production parseTypeCollectionPropertyElt
368
+ add_debug(child, "parseTypeCollectionPropertyElt")
369
+
370
+ unless attrs.empty?
371
+ warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
372
+ add_debug(child, warn)
373
+ raise RDF::ReaderError.new(warn) if @strict
374
+ end
375
+
376
+ # For element event e with possibly empty nodeElementList l. Set s:=list().
377
+ # For each element event f in l, n := bnodeid(identifier := generated-blank-node-id()) and append n to s to give a sequence of events.
378
+ s = element_nodes.map { RDF::Node.new }
379
+ n = s.first || RDF["nil"]
380
+ add_triple(child, subject, predicate, n)
381
+ reify(id, child, subject, predicate, n, child_ec) if id
382
+
383
+ # Add first/rest entries for all list elements
384
+ s.each_index do |i|
385
+ n = s[i]
386
+ o = s[i+1]
387
+ f = element_nodes[i]
388
+
389
+ new_ec = child_ec.clone(nil)
390
+ object = nodeElement(f, new_ec)
391
+ add_triple(child, n, RDF.first, object)
392
+ add_triple(child, n, RDF.rest, o ? o : RDF.nil)
393
+ end
394
+ elsif parseType # Literal or Other
395
+ # Production parseTypeResourcePropertyElt
396
+ add_debug(child, parseType == "Literal" ? "parseTypeResourcePropertyElt" : "parseTypeOtherPropertyElt (#{parseType})")
397
+
398
+ unless attrs.empty?
399
+ warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
400
+ add_debug(child, warn)
401
+ raise RDF::ReaderError.new(warn) if @strict
402
+ end
403
+
404
+ if resourceAttr
405
+ warn = "illegal rdf:resource"
406
+ add_debug(child, warn)
407
+ raise RDF::ReaderError.new(warn) if @strict
408
+ end
409
+
410
+ object = RDF::Literal.new(child.children, :datatype => XML_LITERAL, :namespaces => child_ec.uri_mappings)
411
+ add_triple(child, subject, predicate, object)
412
+ elsif text_nodes.length == 0 && element_nodes.length == 0
413
+ # Production emptyPropertyElt
414
+ add_debug(child, "emptyPropertyElt")
415
+
416
+ if attrs.empty? && resourceAttr.nil? && nodeID.nil?
417
+ literal = RDF::Literal.new("", :language => ec.language)
418
+ add_triple(child, subject, predicate, literal)
419
+
420
+ # Reification
421
+ reify(id, child, subject, predicate, literal, child_ec) if id
422
+ else
423
+ if resourceAttr
424
+ resource = ec.base.join(resourceAttr)
425
+ elsif nodeID
426
+ resource = RDF::Node.new(nodeID)
427
+ else
428
+ resource = RDF::Node.new
429
+ end
430
+
431
+ # produce triples for attributes
432
+ attrs.each_pair do |attr, val|
433
+ add_debug(el, "attr: #{attr.name}='#{val}'")
434
+
435
+ if attr.uri.to_s == RDF.type
436
+ add_triple(child, resource, RDF.type, val)
437
+ else
438
+ # Check for illegal attributes
439
+ next unless is_propertyAttr?(attr)
440
+
441
+ # Attributes not in RDF.type
442
+ lit = RDF::Literal.new(val, :language => child_ec.language)
443
+ add_triple(child, resource, attr.uri.to_s, lit)
444
+ end
445
+ end
446
+ add_triple(child, subject, predicate, resource)
447
+
448
+ # Reification
449
+ reify(id, child, subject, predicate, resource, child_ec) if id
450
+ end
451
+ end
452
+ end
453
+
454
+ # Return subject
455
+ subject
456
+ end
457
+
458
+ private
459
+ # Reify subject, predicate, and object given the EvaluationContext (ec) and current XMl element (el)
460
+ def reify(id, el, subject, predicate, object, ec)
461
+ add_debug(el, "reify, id: #{id}")
462
+ rsubject = ec.base.join("#" + id)
463
+ add_triple(el, rsubject, RDF.subject, subject)
464
+ add_triple(el, rsubject, RDF.predicate, predicate)
465
+ add_triple(el, rsubject, RDF.object, object)
466
+ add_triple(el, rsubject, RDF.type, RDF.Statement)
467
+ end
468
+
469
+ # Figure out the subject from the element.
470
+ def parse_subject(el, ec)
471
+ old_property_check(el)
472
+
473
+ nodeElementURI_check(el)
474
+ about = el.attribute("about")
475
+ id = el.attribute("ID")
476
+ nodeID = el.attribute("nodeID")
477
+
478
+ if nodeID && about
479
+ add_debug(el, "Cannot have rdf:nodeID and rdf:about.")
480
+ raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:about.") if @strict
481
+ elsif nodeID && id
482
+ add_debug(el, "Cannot have rdf:nodeID and rdf:ID.")
483
+ raise RDF::ReaderError.new("Cannot have rdf:nodeID and rdf:ID.") if @strict
484
+ end
485
+
486
+ case
487
+ when id
488
+ add_debug(el, "parse_subject, id: '#{id.value.rdf_escape}'")
489
+ id_check(el, id.value.rdf_escape, ec.base) # Returns URI
490
+ when nodeID
491
+ # The value of rdf:nodeID must match the XML Name production
492
+ nodeID = nodeID_check(el, nodeID.value.rdf_escape)
493
+ add_debug(el, "parse_subject, nodeID: '#{nodeID}")
494
+ RDF::Node.new(nodeID, @named_bnodes)
495
+ when about
496
+ about = about.value.rdf_escape
497
+ add_debug(el, "parse_subject, about: '#{about}'")
498
+ ec.base.join(about)
499
+ else
500
+ add_debug(el, "parse_subject, BNode")
501
+ RDF::Node.new
502
+ end
503
+ end
504
+
505
+ # ID attribute must be an NCName
506
+ def id_check(el, id, base)
507
+ if NC_REGEXP.match(id)
508
+ # ID may only be specified once for the same URI
509
+ if base
510
+ uri = base.join("##{id}", base)
511
+ if @id_mapping[id] && @id_mapping[id] == uri
512
+ warn = "ID addtribute '#{id}' may only be defined once for the same URI"
513
+ add_debug(el, warn)
514
+ raise RDF::ReaderError.new(warn) if @strict
515
+ end
516
+
517
+ @id_mapping[id] = uri
518
+ # Returns URI, in this case
519
+ else
520
+ id
521
+ end
522
+ else
523
+ warn = "ID addtribute '#{id}' must be a NCName"
524
+ add_debug(el, "ID addtribute '#{id}' must be a NCName")
525
+ add_debug(el, warn)
526
+ raise RDF::ReaderError.new(warn) if @strict
527
+ nil
528
+ end
529
+ end
530
+
531
+ # nodeID must be an XML Name
532
+ # nodeID must pass Production rdf-id
533
+ def nodeID_check(el, nodeID)
534
+ if NC_REGEXP.match(nodeID)
535
+ nodeID
536
+ else
537
+ add_debug(el, "nodeID addtribute '#{nodeID}' must be an XML Name")
538
+ raise RDF::ReaderError.new("nodeID addtribute '#{nodeID}' must be a NCName") if @strict
539
+ nil
540
+ end
541
+ end
542
+
543
+ # Is this attribute a Property Attribute?
544
+ def is_propertyAttr?(attr)
545
+ if ([RDF.Description.to_s, RDF.li.to_s] + OLD_TERMS).include?(attr.uri.to_s)
546
+ warn = "Invalid use of rdf:#{attr.name}"
547
+ add_debug(attr, warn)
548
+ raise RDF::ReaderError.new(warn) if @strict
549
+ return false
550
+ end
551
+ !CORE_SYNTAX_TERMS.include?(attr.uri.to_s) && attr.namespace && attr.namespace.href != XML_NS.uri.to_s
552
+ end
553
+
554
+ # Check Node Element name
555
+ def nodeElementURI_check(el)
556
+ if (CORE_SYNTAX_TERMS + [RDF.li.to_s] + OLD_TERMS).include?(el.uri.to_s)
557
+ warn = "Invalid use of rdf:#{el.name}"
558
+ add_debug(el, warn)
559
+ raise RDF::ReaderError.new(warn) if @strict
560
+ end
561
+ end
562
+
563
+ # Check Property Element name
564
+ def propertyElementURI_check(el)
565
+ if (CORE_SYNTAX_TERMS + [RDF.Description.to_s] + OLD_TERMS).include?(el.uri.to_s)
566
+ warn = "Invalid use of rdf:#{el.name}"
567
+ add_debug(el, warn)
568
+ raise RDF::ReaderError.new(warn) if @strict
569
+ end
570
+ end
571
+
572
+ # Check for the use of an obsolete RDF property
573
+ def old_property_check(el)
574
+ el.attribute_nodes.each do |attr|
575
+ if OLD_TERMS.include?(attr.uri.to_s)
576
+ add_debug(el, "Obsolete attribute '#{attr.uri}'")
577
+ raise RDF::ReaderError.new("Obsolete attribute '#{attr.uri}'") if @strict
578
+ end
579
+ end
580
+ end
581
+
582
+ end
583
+ end
@@ -0,0 +1,21 @@
1
+ module RDF::RDFXML::VERSION
2
+ MAJOR = 0
3
+ MINOR = 0
4
+ TINY = 1
5
+ EXTRA = nil
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ STRING << "-#{EXTRA}" if EXTRA
9
+
10
+ ##
11
+ # @return [String]
12
+ def self.to_s() STRING end
13
+
14
+ ##
15
+ # @return [String]
16
+ def self.to_str() STRING end
17
+
18
+ ##
19
+ # @return [Array(Integer, Integer, Integer)]
20
+ def self.to_a() [MAJOR, MINOR, TINY] end
21
+ end
File without changes
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdf-rdfxml
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Gregg Kellogg
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-06-03 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rdf
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 0
32
+ - 1
33
+ - 6
34
+ version: 0.1.6
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: nokogiri
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 29
46
+ segments:
47
+ - 1
48
+ - 3
49
+ - 3
50
+ version: 1.3.3
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :development
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: rdf-spec
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id004
81
+ - !ruby/object:Gem::Dependency
82
+ name: activesupport
83
+ prerelease: false
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 2
92
+ - 3
93
+ - 0
94
+ version: 2.3.0
95
+ type: :development
96
+ version_requirements: *id005
97
+ description: " RDF::RDFXML is an RDF/XML reader and writer for Ruby using the RDF.rb library suite.\n"
98
+ email: gregg@kellogg-assoc.com
99
+ executables: []
100
+
101
+ extensions: []
102
+
103
+ extra_rdoc_files:
104
+ - AUTHORS
105
+ - History.txt
106
+ - README.rdoc
107
+ files:
108
+ - .yardopts
109
+ - AUTHORS
110
+ - History.txt
111
+ - README.rdoc
112
+ - Rakefile
113
+ - VERSION
114
+ - example.rb
115
+ - lib/rdf/rdfxml.rb
116
+ - lib/rdf/rdfxml/format.rb
117
+ - lib/rdf/rdfxml/reader.rb
118
+ - lib/rdf/rdfxml/version.rb
119
+ - lib/rdf/rdfxml/writer.rb
120
+ has_rdoc: true
121
+ homepage: http://github.com/gkellogg/rdf-rdfxml
122
+ licenses: []
123
+
124
+ post_install_message:
125
+ rdoc_options:
126
+ - --charset=UTF-8
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ hash: 3
144
+ segments:
145
+ - 0
146
+ version: "0"
147
+ requirements: []
148
+
149
+ rubyforge_project:
150
+ rubygems_version: 1.3.7
151
+ signing_key:
152
+ specification_version: 3
153
+ summary: RDF/XML reader/writer for RDF.rb.
154
+ test_files: []
155
+