rdf-xsd 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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