rdf-xsd 0.3.4 → 0.3.5

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.
@@ -9,9 +9,11 @@ This gem adds additional RDF::Literal subclasses for extended [XSD datatypes][]
9
9
  * Additional xsd:integer subtypes
10
10
  * xsd:float based on xsd:double
11
11
  * xsd:duration
12
+ * rdf:XMLLiteral
13
+ * XML Exclusive Canonicalization (Nokogiri & REXML)
14
+ * XML Literal comparisions (EquivalentXml, ActiveSupport or String)
12
15
 
13
- Examples
14
- --------
16
+ ## Examples
15
17
 
16
18
  require 'rdf'
17
19
  require 'rdf/xsd'
@@ -46,11 +48,15 @@ Full documentation available on [Rubydoc.info][XSD doc]
46
48
  * {RDF::Literal::MonthDay}
47
49
  * {RDF::Literal::Month}
48
50
  * {RDF::Literal::Day}
51
+ * {RDF::Literal::XML}
49
52
 
50
53
  ## Dependencies
51
54
 
52
55
  * [Ruby](http://ruby-lang.org/) (>= 1.8.7) or (>= 1.8.1 with [Backports][])
53
56
  * [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.3.4)
57
+ * Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.5.0)
58
+ * Soft dependency on [EquivalentXML](http://rubygems.org/gems/equivalent-xml) (>= 0.2.8)
59
+ * Soft dependency on [ActiveSupport](http://rubygems.org/gems/activesupport) (>= 2.3.0)
54
60
 
55
61
  ## Installation
56
62
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.4
1
+ 0.3.5
@@ -139,11 +139,11 @@ module RDF; class Literal
139
139
  case other
140
140
  when Duration
141
141
  return super unless other.valid?
142
- self.to_f == something.to_f
142
+ self.to_f == other.to_f
143
143
  when String
144
- self.to_s(:xml) == something
144
+ self.to_s(:xml) == other
145
145
  when Numeric
146
- self.to_f == something
146
+ self.to_f == other
147
147
  when Literal::DateTime, Literal::Time, Literal::Date
148
148
  false
149
149
  else
@@ -0,0 +1,203 @@
1
+ begin
2
+ require 'nokogiri'
3
+ rescue LoadError => e
4
+ end
5
+ require 'rexml/document'
6
+
7
+ if defined?(::Nokogiri)
8
+ module ::Nokogiri::XML
9
+ ##
10
+ # XML Exclusive Canonicalization (c14n) for Nokogiri.
11
+ #
12
+ # Classes mixin this module to implement canonicalization methods.
13
+ #
14
+ # This implementation acts in two parts, first to canonicalize the Node
15
+ # or NoteSet in the context of its containing document, and second to
16
+ # serialize to a lexical representation.
17
+ #
18
+ # @see # @see http://www.w3.org/TR/xml-exc-c14n/
19
+ class Node
20
+ ##
21
+ # Canonicalize the Node. Return a new instance of this node
22
+ # which is canonicalized and marked as such
23
+ #
24
+ # @param [Hash{Symbol => Object}] options
25
+ # @option options [Hash{String => String}] :namespaces
26
+ # Namespaces to apply to node.
27
+ # @option options [#to_s] :language
28
+ # Language to set on node, unless an xml:lang is already set.
29
+ def c14nxl(options = {})
30
+ @c14nxl = true
31
+ self
32
+ end
33
+
34
+ ##
35
+ # Serialize a canonicalized Node or NodeSet to XML
36
+ #
37
+ # Override standard #to_s implementation to output in c14n representation
38
+ # if the Node or NodeSet is marked as having been canonicalized
39
+ def to_s_with_c14nxl
40
+ if instance_variable_defined?(:@c14nxl)
41
+ serialize(:save_with => ::Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)
42
+ else
43
+ to_s_without_c14nxl
44
+ end
45
+ end
46
+
47
+ alias_method :to_s_without_c14nxl, :to_s
48
+ alias_method :to_s, :to_s_with_c14nxl
49
+ end
50
+
51
+ class Element
52
+ ##
53
+ # Canonicalize the Element. Return a new instance of this node
54
+ # which is canonicalized and marked as such.
55
+ #
56
+ # Apply namespaces either passed as an option, or that are in scope.
57
+ #
58
+ # @param [Hash{Symbol => Object}] options
59
+ # From {Nokogiri::XML::Node#c14nxl}
60
+ def c14nxl(options = {})
61
+ options[:namespaces] ||= self.namespace_scopes.compact.inject({}) do |memo, ns|
62
+ memo[ns.prefix] = ns.href.to_s
63
+ memo
64
+ end
65
+ element = self.clone
66
+
67
+ # Add in-scope namespace definitions
68
+ options[:namespaces].each do |prefix, href|
69
+ if prefix.to_s.empty?
70
+ element.default_namespace = href unless element.namespace
71
+ else
72
+ element.add_namespace(prefix.to_s, href) unless element.namespaces[prefix.to_s]
73
+ end
74
+ end
75
+
76
+ # Add language
77
+ element["xml:lang"] = options[:language].to_s if
78
+ options[:language] &&
79
+ element.attribute_with_ns("lang", "http://www.w3.org/XML/1998/namespace").to_s.empty? &&
80
+ element.attribute("lang").to_s.empty?
81
+
82
+ element
83
+ end
84
+ end
85
+
86
+ class NodeSet
87
+ ##
88
+ # Canonicalize the NodeSet. Return a new NodeSet marked
89
+ # as being canonical with all child nodes canonicalized.
90
+ #
91
+ # @param [Hash{Symbol => Object}] options
92
+ # Passed to {Nokogiri::XML::Node#c14nxl}
93
+ def c14nxl(options = {})
94
+ # Create a new NodeSet
95
+ set = self.clone
96
+ set.instance_variable_set(:@c14nxl, true)
97
+
98
+ self.each {|c| set << c.c14nxl(options)}
99
+ set
100
+ end
101
+
102
+ ##
103
+ # Serialize a canonicalized Node or NodeSet to XML
104
+ #
105
+ # Override standard #to_s implementation to output in c14n representation
106
+ # if the Node or NodeSet is marked as having been canonicalized
107
+ def to_s_with_c14nxl
108
+ if instance_variable_defined?(:@c14nxl)
109
+ to_a.map {|c| c.serialize(:save_with => ::Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)}.join("")
110
+ else
111
+ to_s_without_c14nxl
112
+ end
113
+ end
114
+
115
+ alias_method :to_s_without_c14nxl, :to_s
116
+ alias_method :to_s, :to_s_with_c14nxl
117
+ end
118
+
119
+ class Document
120
+ def doctype
121
+ self.children.first rescue false
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ ## REXML C14N
128
+ class Array
129
+ ##
130
+ # Canonicalize the NodeSet. Return a new NodeSet marked
131
+ # as being canonical with all child nodes canonicalized.
132
+ #
133
+ # @param [Hash{Symbol => Object}] options
134
+ # Passed to {Nokogiri::XML::Node#c14nxl}
135
+ def c14nxl(options = {})
136
+ # Create a new NodeSet
137
+ set = []
138
+ set.instance_variable_set(:@c14nxl, true)
139
+
140
+ # Unless passed a set of namespaces, figure them out from namespace_scopes
141
+ #options[:namespaces] ||= first.parent.namespace_scopes.compact.inject({}) do |memo, ns|
142
+ # memo[ns.prefix] = ns.href.to_s
143
+ # memo
144
+ #end
145
+
146
+ self.each {|c| set << (c.respond_to?(:c14nxl) ? c.c14nxl(options) : c)}
147
+ set
148
+ end
149
+
150
+ ##
151
+ # Serialize a canonicalized Node or NodeSet to XML
152
+ #
153
+ # Override standard #to_s implementation to output in c14n representation
154
+ # if the Node or NodeSet is marked as having been canonicalized
155
+ def to_s_with_c14nxl
156
+ if instance_variable_defined?(:@c14nxl)
157
+ map {|c| c.to_s}.join("")
158
+ else
159
+ to_s_without_c14nxl
160
+ end
161
+ end
162
+
163
+ alias_method :to_s_without_c14nxl, :to_s
164
+ alias_method :to_s, :to_s_with_c14nxl
165
+ end
166
+
167
+ class REXML::Element
168
+ ##
169
+ # Canonicalize the Element. Return a new instance of this node
170
+ # which is canonicalized and marked as such.
171
+ #
172
+ # Apply namespaces either passed as an option, or that are in scope.
173
+ #
174
+ # @param [Hash{Symbol => Object}] options
175
+ # From {Nokogiri::XML::Node#c14nxl}
176
+ def c14nxl(options = {})
177
+ # Add in-scope namespace definitions, unless supplied
178
+ options[:namespaces] ||= self.namespaces
179
+ element = options[:inplace] ? self : self.dup
180
+
181
+ # Add in-scope namespace definitions
182
+ options[:namespaces].each do |prefix, href|
183
+ if prefix.to_s.empty?
184
+ element.add_attribute("xmlns", href) unless element.attribute("xmlns")
185
+ else
186
+ element.add_attribute("xmlns:#{prefix}", href) unless element.attribute("xmlns:#{prefix}")
187
+ end
188
+ end
189
+
190
+ # Add language
191
+ element.add_attribute("xml:lang", options[:language].to_s) if
192
+ options[:language] &&
193
+ element.attribute("lang", "http://www.w3.org/XML/1998/namespace").to_s.empty? &&
194
+ element.attribute("lang").to_s.empty?
195
+
196
+ # Make sure it formats as open/close tags
197
+ element.text = "" if element.text == nil && element.children.empty?
198
+
199
+ # Recurse through children to ensure tags are set properly
200
+ element.children.each {|c| c.c14nxl(:inplace => true, :namespaces => {}) if c.is_a?(REXML::Element)}
201
+ element
202
+ end
203
+ end
@@ -0,0 +1,139 @@
1
+ # Use Nokogiri when available, and REXML otherwise:
2
+ begin
3
+ raise LoadError, "not with java" if RUBY_PLATFORM == "java"
4
+ require 'nokogiri'
5
+ begin
6
+ require 'equivalent-xml'
7
+ rescue LoadError => e
8
+ STDERR.puts "Could not load gem 'equivalent-xml'; XMLLiteral comparison performed using REXML"
9
+ end
10
+ rescue LoadError => e
11
+ :rexml
12
+ end
13
+
14
+ module RDF; class Literal
15
+ ##
16
+ # An XML literal.
17
+ #
18
+ # XML Literals are maintained in a lexical form, unless an object form is provided.
19
+ # The both lexical and object forms are presumed to be in Exclusive Canonical XML.
20
+ # As generating this form is dependent on the context of the XML Literal from the
21
+ # original document, canonicalization cannot be performed directly within this
22
+ # class.
23
+ #
24
+ # This gem includes Exclusive Canonical XML extensions {Nokogiri::XML::Node#c14nxl},
25
+ # {Nokogiri::XML::NodeSet#c14nxl}, {REXML::Element#c14nxl} and {Array#c14nxl} (necessary
26
+ # for REXML node children, which is the REXML implementation of a NodeSet)
27
+ #
28
+ # @see http://www.w3.org/TR/rdf-concepts/#section-XMLLiteral
29
+ # @see http://www.w3.org/TR/rdfa-core/#s_xml_literals
30
+ # @see http://www.w3.org/TR/xml-exc-c14n/
31
+ # @since 0.2.1
32
+ class XML < Literal
33
+ #DATATYPE = RDF.XMLLiteral
34
+ #GRAMMAR = nil
35
+
36
+ ##
37
+ # @param [Object] value
38
+ # @option options [String] :lexical (nil)
39
+ # @option options [:nokogiri, :rexml] :library
40
+ # Library to use, defaults to :nokogiri if available, :rexml otherwise
41
+ def initialize(value, options = {})
42
+ @datatype = options[:datatype] || DATATYPE
43
+ @string = options[:lexical] if options.has_key?(:lexical)
44
+ if value.is_a?(String)
45
+ @string ||= value
46
+ else
47
+ @object = value
48
+ end
49
+
50
+ @library = case options[:library]
51
+ when nil
52
+ # Use Nokogiri when available, and REXML or Hpricot otherwise:
53
+ (defined?(::Nokogiri) && RUBY_PLATFORM != 'java') ? :nokogiri : :rexml
54
+ when :nokogiri, :rexml
55
+ options[:library]
56
+ else
57
+ raise ArgumentError.new("expected :rexml or :nokogiri, but got #{options[:library].inspect}")
58
+ end
59
+ end
60
+
61
+ ##
62
+ # Parse value, if necessary
63
+ #
64
+ # @return [Object]
65
+ def object
66
+ @object ||= case @library
67
+ when :nokogiri then parse_nokogiri(value)
68
+ when :rexml then parse_rexml(value)
69
+ end
70
+ end
71
+
72
+ def to_s
73
+ @string ||= (@object.is_a?(Array) ? @object.map(&:to_s).join("") : @object.to_s)
74
+ end
75
+
76
+ ##
77
+ # XML Equivalence. XML Literals can be compared with each other or with xsd:strings
78
+ #
79
+ # @param [Object] other
80
+ # @return [Boolean] `true` or `false`
81
+ #
82
+ # @see http://www.w3.org/TR/rdf-concepts/#section-XMLLiteral
83
+ def eql?(other)
84
+ if other.is_a?(Literal::XML)
85
+ case @library
86
+ when :nokogiri then equivalent_nokogiri(other)
87
+ when :rexml then equivalent_rexml(other)
88
+ end
89
+ elsif other.is_a?(Literal) && (other.plain? || other.datatype == RDF::XSD.string)
90
+ value == other.value
91
+ else
92
+ super
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ # Nokogiri implementations
99
+ if defined?(::Nokogiri)
100
+ ##
101
+ # Parse the value either as a NodeSet, as results are equivalent if it is just a node
102
+ def parse_nokogiri(value)
103
+ Nokogiri::XML.parse("<root>#{value}</root>").root.children
104
+ end
105
+
106
+ # Use equivalent-xml to determine equivalence
107
+ def equivalent_nokogiri(other)
108
+ if defined?(::EquivalentXml)
109
+ EquivalentXml.equivalent?(object, other.object)
110
+ else
111
+ equivalent_rexml(other)
112
+ end
113
+ end
114
+ end
115
+
116
+ ##
117
+ # Parse the value either as a NodeSet, as results are equivalent if it is just a node
118
+ def parse_rexml(value)
119
+ REXML::Document.new("<root>#{value}</root>").root.children
120
+ end
121
+
122
+
123
+ # Simple equivalence test for REXML
124
+ def equivalent_rexml(other)
125
+ begin
126
+ require 'active_support/core_ext'
127
+ rescue LoadError => e
128
+ # string equivalence
129
+ end
130
+
131
+ if Hash.respond_to?(:from_xml)
132
+ Hash.from_xml("<root>#{self}</root>") == Hash.from_xml("<root>#{other}</root>")
133
+ else
134
+ # Poor mans equivalent
135
+ value == other.value
136
+ end
137
+ end
138
+ end # class XML
139
+ end; end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf-xsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-09-15 00:00:00.000000000 Z
13
+ date: 2011-11-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rdf
17
- requirement: &2160138240 !ruby/object:Gem::Requirement
17
+ requirement: &2152226860 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,54 @@ dependencies:
22
22
  version: 0.3.4
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2160138240
25
+ version_requirements: *2152226860
26
+ - !ruby/object:Gem::Dependency
27
+ name: nokogiri
28
+ requirement: &2152226100 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2152226100
37
+ - !ruby/object:Gem::Dependency
38
+ name: equivalent-xml
39
+ requirement: &2152225100 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: 0.2.8
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2152225100
48
+ - !ruby/object:Gem::Dependency
49
+ name: active_support
50
+ requirement: &2152224320 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: 3.0.0
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2152224320
59
+ - !ruby/object:Gem::Dependency
60
+ name: i18n
61
+ requirement: &2152223060 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: 0.6.0
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *2152223060
26
70
  - !ruby/object:Gem::Dependency
27
71
  name: rspec
28
- requirement: &2160117520 !ruby/object:Gem::Requirement
72
+ requirement: &2152221540 !ruby/object:Gem::Requirement
29
73
  none: false
30
74
  requirements:
31
75
  - - ! '>='
@@ -33,10 +77,10 @@ dependencies:
33
77
  version: 2.5.0
34
78
  type: :development
35
79
  prerelease: false
36
- version_requirements: *2160117520
80
+ version_requirements: *2152221540
37
81
  - !ruby/object:Gem::Dependency
38
82
  name: rdf-spec
39
- requirement: &2160116640 !ruby/object:Gem::Requirement
83
+ requirement: &2152219980 !ruby/object:Gem::Requirement
40
84
  none: false
41
85
  requirements:
42
86
  - - ! '>='
@@ -44,10 +88,10 @@ dependencies:
44
88
  version: 0.3.2
45
89
  type: :development
46
90
  prerelease: false
47
- version_requirements: *2160116640
91
+ version_requirements: *2152219980
48
92
  - !ruby/object:Gem::Dependency
49
93
  name: yard
50
- requirement: &2160115500 !ruby/object:Gem::Requirement
94
+ requirement: &2152218640 !ruby/object:Gem::Requirement
51
95
  none: false
52
96
  requirements:
53
97
  - - ! '>='
@@ -55,7 +99,7 @@ dependencies:
55
99
  version: 0.6.0
56
100
  type: :development
57
101
  prerelease: false
58
- version_requirements: *2160115500
102
+ version_requirements: *2152218640
59
103
  description: Adds RDF::Literal subclasses for extended XSD datatypes.
60
104
  email: public-rdf-ruby@w3.org
61
105
  executables: []
@@ -70,8 +114,10 @@ files:
70
114
  - lib/rdf/xsd/date.rb
71
115
  - lib/rdf/xsd/double.rb
72
116
  - lib/rdf/xsd/duration.rb
117
+ - lib/rdf/xsd/extensions.rb
73
118
  - lib/rdf/xsd/integer.rb
74
119
  - lib/rdf/xsd/version.rb
120
+ - lib/rdf/xsd/xml.rb
75
121
  - lib/rdf/xsd.rb
76
122
  homepage: http://github.com/gkellogg/rdf-xsd
77
123
  licenses:
@@ -99,3 +145,4 @@ signing_key:
99
145
  specification_version: 3
100
146
  summary: Extended XSD Datatypes for RDF.rb.
101
147
  test_files: []
148
+ has_rdoc: false