rdf-rdfxml 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,23 @@
1
+ === 0.0.3
2
+ * Added patches for the following:
3
+ * RDF::Graph#properties
4
+ * RDF::Graph#seq (Output rdf:Seq elements in order)
5
+ * RDF::Graph#type_of
6
+ * RDF::Literal.xmlliteral (Create literal and normalize XML)
7
+ * RDF::Literal#xmlliteral?
8
+ * RDF::Literal#anonymous? (missing from library)
9
+ * RDF::Literal#to_s (only one of @lang or ^^type, not both)
10
+ * RDF::URI#join (Don't add trailing '/')
11
+ * Reader fixes
12
+ * Writer complete
13
+ * Spec status
14
+ * Isomorphic XMLLiteral tests fail due to attribute order variation
15
+ * Reader parsing multi-line quite in NTriples test file fails due to lack of support in RDF::NTriples
16
+ * A couple of URI normalizations fail:
17
+ * should create <http://foo/> from <http://foo#> and ''
18
+ * should create <http://foo/bar> from <http://foo/bar#> and ''
19
+ * Writer test needs Turtle reader
20
+
1
21
  === 0.0.2
2
22
  * Added specs from RdfContext
3
23
  * Added array_hacks, nokogiri_hacks, and rdf_escape
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -3,8 +3,8 @@ module RDF::RDFXML
3
3
  # RDFXML format specification.
4
4
  #
5
5
  # @example Obtaining an RDFXML format class
6
- # RDF::Format.for(:rdf) # RDF::RDFXML::Format
7
- # RDF::Format.for(:xml) # RDF::RDFXML::Format
6
+ # RDF::Format.for(:rdf) # RDF::RDFXML::Format
7
+ # RDF::Format.for(:rdfxml) # RDF::RDFXML::Format
8
8
  # RDF::Format.for("etc/foaf.xml")
9
9
  # RDF::Format.for(:file_name => "etc/foaf.xml")
10
10
  # RDF::Format.for(:file_extension => "xml")
@@ -0,0 +1,34 @@
1
+ module RDF
2
+ class Graph
3
+ # Resource properties
4
+ #
5
+ # Properties arranged as a hash with the predicate Term as index to an array of resources or literals
6
+ #
7
+ # Example:
8
+ # graph.load(':foo a :bar; rdfs:label "An example" .', "http://example.com/")
9
+ # graph.resources(URI.new("http://example.com/subject")) =>
10
+ # {
11
+ # "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" => [<http://example.com/#bar>],
12
+ # "http://example.com/#label" => ["An example"]
13
+ # }
14
+ def properties(subject, recalc = false)
15
+ @properties ||= {}
16
+ @properties.delete(subject.to_s) if recalc
17
+ @properties[subject.to_s] ||= begin
18
+ hash = Hash.new
19
+ self.query(:subject => subject) do |statement|
20
+ pred = statement.predicate.to_s
21
+
22
+ hash[pred] ||= []
23
+ hash[pred] << statement.object
24
+ end
25
+ hash
26
+ end
27
+ end
28
+
29
+ # Get type(s) of subject, returns a list of symbols
30
+ def type_of(subject)
31
+ query(:subject => subject, :predicate => RDF.type).map {|st| st.object}
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ module RDF
2
+ class Literal
3
+ # Support for XML Literals
4
+ # Is this an XMLLiteral?
5
+ def xmlliteral?
6
+ datatype == RDF['XMLLiteral']
7
+ end
8
+
9
+ def anonymous?; false; end unless respond_to?(:anonymous?)
10
+
11
+ ##
12
+ # Returns a string representation of this literal.
13
+ #
14
+ # @return [String]
15
+ def to_s
16
+ quoted = value # FIXME
17
+ output = "\"#{quoted}\""
18
+ output << "@#{language}" if has_language? && !has_datatype?
19
+ output << "^^<#{datatype}>" if has_datatype?
20
+ output
21
+ end
22
+
23
+ # Normalize an XML Literal, by adding necessary namespaces.
24
+ # This should be done as part of initialize
25
+ #
26
+ # namespaces is a hash of prefix => URIs
27
+ def self.xmlliteral(contents, options = {})
28
+ options[:namespaces] ||= {}
29
+ l = new("", :datatype => RDF["XMLLiteral"])
30
+
31
+ if contents.is_a?(String)
32
+ ns_hash = {}
33
+ options[:namespaces].each_pair do |prefix, uri|
34
+ attr = prefix.to_s.empty? ? "xmlns" : "xmlns:#{prefix}"
35
+ ns_hash[attr] = uri.to_s
36
+ end
37
+ ns_strs = []
38
+ ns_hash.each_pair {|a, u| ns_strs << "#{a}=\"#{u}\""}
39
+
40
+ # Add inherited namespaces to created root element so that they're inherited to sub-elements
41
+ contents = Nokogiri::XML::Document.parse("<foo #{ns_strs.join(" ")}>#{contents}</foo>").root.children
42
+ end
43
+
44
+ # Add already mapped namespaces and language
45
+ l.value = contents.map do |c|
46
+ if c.is_a?(Nokogiri::XML::Element)
47
+ c = Nokogiri::XML.parse(c.dup.to_s).root
48
+ # Gather namespaces from self and decendant nodes
49
+ c.traverse do |n|
50
+ ns = n.namespace
51
+ next unless ns
52
+ prefix = ns.prefix ? "xmlns:#{ns.prefix}" : "xmlns"
53
+ c[prefix] = ns.href.to_s unless c.namespaces[prefix]
54
+ end
55
+
56
+ # Add lanuage
57
+ if options[:language] && c["lang"].to_s.empty?
58
+ c["xml:lang"] = options[:language]
59
+ end
60
+ end
61
+ c.to_html(:save_with => Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)
62
+ end.join("")
63
+ l
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,57 @@
1
+ module RDF
2
+ class URI
3
+ #unless defined?(:vocab)
4
+ def vocab
5
+ # Find vocabulary if not assigned
6
+ return @vocab if @vocab
7
+
8
+ Vocabulary.each do |vocab|
9
+ return self.vocab = vocab if to_s.index(vocab.to_uri.to_s) == 0
10
+ end
11
+ nil
12
+ end
13
+
14
+ def vocab=(value)
15
+ raise "Vocab #{value.inspect} is not a Vocabulary!" if value.is_a?(Array)
16
+ @vocab = value
17
+ end
18
+
19
+ def qname
20
+ @qname ||= if vocab
21
+ raise "Vocab #{vocab.inspect} is not a Vocabulary!" if vocab.is_a?(Array)
22
+ vocab_name = vocab.__name__.to_s.split('::').last.downcase
23
+ local_name = to_s[vocab.to_uri.to_s.size..-1]
24
+ vocab_name && local_name && [vocab_name.to_sym, local_name.to_sym]
25
+ end
26
+ end
27
+ #end
28
+ end
29
+
30
+ class Vocabulary
31
+ def self.[](property)
32
+ @prop_uri ||= {}
33
+ @prop_uri[property] ||= begin
34
+ uri = RDF::URI.new([to_s, property.to_s].join(''))
35
+ uri.vocab = self
36
+ uri
37
+ end
38
+ end
39
+
40
+ def [](property)
41
+ @prop_uri ||= {}
42
+ @prop_uri[property] ||= begin
43
+ uri = RDF::URI.new([to_s, property.to_s].join(''))
44
+ uri.vocab = self
45
+ uri
46
+ end
47
+ end
48
+
49
+ def to_uri
50
+ @uri ||= begin
51
+ uri = RDF::URI.new(to_s)
52
+ uri.vocab = self
53
+ uri
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,34 @@
1
+ require 'rdf/rdfxml/patches/graph_properties'
2
+ module RDF
3
+ class Graph
4
+ # Returns ordered rdf:_n objects or rdf:first, rdf:rest for a given subject
5
+ def seq(subject)
6
+ props = properties(subject)
7
+ rdf_type = (props[RDF.type.to_s] || []).map {|t| t.to_s}
8
+
9
+ #puts "seq; #{rdf_type} #{rdf_type - [RDF_NS.Seq, RDF_NS.Bag, RDF_NS.Alt]}"
10
+ if !(rdf_type - [RDF.Seq, RDF.Bag, RDF.Alt]).empty?
11
+ props.keys.select {|k| k.match(/#{RDF.to_s}_(\d)$/)}.
12
+ sort_by {|i| i.sub(RDF._.to_s, "").to_i}.
13
+ map {|key| props[key]}.
14
+ flatten
15
+ elsif !self.query(:subject => subject, :predicate => RDF.first).empty?
16
+ # N3-style first/rest chain
17
+ list = []
18
+ while subject != RDF_NS.nil
19
+ props = properties(subject)
20
+ f = props[RDF.first.to_s]
21
+ if f.to_s.empty? || f.first == RDF.nil
22
+ subject = RDF.nil
23
+ else
24
+ list += f
25
+ subject = props[RDF.rest.to_s].first
26
+ end
27
+ end
28
+ list
29
+ else
30
+ []
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ module RDF
2
+ class URI
3
+ ##
4
+ # Joins several URIs together.
5
+ #
6
+ # @param [Array<String, URI, #to_str>] uris
7
+ # @return [URI]
8
+ #
9
+ # GK -- don't add a "/" at the end of URIs, due to rdfcore/xmlbase/test002.rdf
10
+ def join(*uris)
11
+ result = @uri
12
+ uris.each do |uri|
13
+ # result.path += '/' unless result.path.match(/[\#\/]$/) || uri.to_s[0..0] == "#"
14
+ result = result.join(uri)
15
+ end
16
+ self.class.new(result)
17
+ end
18
+ end
19
+ end
@@ -24,8 +24,6 @@ module RDF::RDFXML
24
24
  $},
25
25
  Regexp::EXTENDED)
26
26
 
27
- XML_LITERAL = RDF['XMLLiteral']
28
-
29
27
  # The Recursive Baggage
30
28
  class EvaluationContext # :nodoc:
31
29
  attr_reader :base
@@ -42,7 +40,6 @@ module RDF::RDFXML
42
40
  @language = nil
43
41
  @graph = graph
44
42
  @li_counter = 0
45
- @uri_mappings = {}
46
43
 
47
44
  extract_from_element(element) if element
48
45
  end
@@ -128,7 +125,7 @@ module RDF::RDFXML
128
125
  super do
129
126
  @debug = options[:debug]
130
127
  @strict = options[:strict]
131
- @base_uri = RDF::URI.parse(options[:base_uri]) if options[:base_uri]
128
+ @base_uri = RDF::URI.new(options[:base_uri])
132
129
 
133
130
  @id_mapping = Hash.new
134
131
 
@@ -360,7 +357,13 @@ module RDF::RDFXML
360
357
  # Production literalPropertyElt
361
358
  add_debug(child, "literalPropertyElt")
362
359
 
363
- literal = RDF::Literal.new(child.inner_html, :datatype => datatype, :language => child_ec.language)
360
+ literal_opts = {}
361
+ if datatype
362
+ literal_opts[:datatype] = datatype
363
+ else
364
+ literal_opts[:language] = child_ec.language
365
+ end
366
+ literal = RDF::Literal.new(child.inner_html, literal_opts)
364
367
  add_triple(child, subject, predicate, literal)
365
368
  reify(id, child, subject, predicate, literal, ec) if id
366
369
  elsif parseType == "Resource"
@@ -439,7 +442,7 @@ module RDF::RDFXML
439
442
  raise RDF::ReaderError.new(warn) if @strict
440
443
  end
441
444
 
442
- object = RDF::Literal.new(child.children, :datatype => XML_LITERAL, :namespaces => child_ec.uri_mappings)
445
+ object = RDF::Literal.xmlliteral(child.children, :namespaces => child_ec.uri_mappings)
443
446
  add_triple(child, subject, predicate, object)
444
447
  elsif text_nodes.length == 0 && element_nodes.length == 0
445
448
  # Production emptyPropertyElt
@@ -472,7 +475,7 @@ module RDF::RDFXML
472
475
 
473
476
  # Attributes not in RDF.type
474
477
  lit = RDF::Literal.new(val, :language => child_ec.language)
475
- add_triple(child, resource, attr.uri.to_s, lit)
478
+ add_triple(child, resource, attr.uri, lit)
476
479
  end
477
480
  end
478
481
  add_triple(child, subject, predicate, resource)