canon 0.3.1 → 0.3.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8180c4d10ad157f5fd7d401d7c4723a70d53daa90894a43c33016253d0355093
4
- data.tar.gz: 513538a92c8f209b2eeec7ecf2adedf9e2a86de8e2c6c0e807b45522afffa9b3
3
+ metadata.gz: b000e9e89684d66d4f037a950a2121a88717dd6c72d975648742f32b5a83fb9f
4
+ data.tar.gz: c5e8b5ecfdcb8435559be3e6c940e8e8bec99202054b90fa857f9e3afd3097e2
5
5
  SHA512:
6
- metadata.gz: 15bbb37c41f2fe0809be3a1ae9e6e3bf438d7d509eb478b92eb1ace044d511017a257409024c0c7e042bf5dc146af0dbbfc9397c6ffea13a5d410fb9019c716d
7
- data.tar.gz: 81c275d67d47bfeb87a1c5969e90643da41e8816e882a40fa5affa8337fbd3c5bd0ee82428ef63b36bc5dff8338776e8df4da53394d3319663f3167433664785
6
+ metadata.gz: '0804e7a2a07ff2687e363ee2bd0a1e2d00a5fe826e45ae5bd69fe26749bf2e2b1517a6fb2fcd3518e41d7d9bf6bf0b76fd8e704c288293724d27cbc3613978f4'
7
+ data.tar.gz: 6d9dca5aa3c29bbde5d067ca02e2a22c4d7bee098635e0fd8b48df16fbf08102fa713608f1965d198f3ace1c064743916b57d34d7a2cc2a6b845902e1553a045
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.3.1"
4
+ VERSION = "0.3.2"
5
5
  end
@@ -154,11 +154,12 @@ module Canon
154
154
  end
155
155
 
156
156
  def self.build_node_from_nokogiri(nokogiri_node,
157
- preserve_whitespace: false)
157
+ preserve_whitespace: false, inherited_namespaces: nil)
158
158
  case nokogiri_node
159
159
  when Nokogiri::XML::Element
160
160
  build_element_node(nokogiri_node,
161
- preserve_whitespace: preserve_whitespace)
161
+ preserve_whitespace: preserve_whitespace,
162
+ inherited_namespaces: inherited_namespaces)
162
163
  when Nokogiri::XML::Text, Nokogiri::XML::CDATA
163
164
  build_text_node(nokogiri_node,
164
165
  preserve_whitespace: preserve_whitespace)
@@ -169,56 +170,44 @@ preserve_whitespace: false)
169
170
  end
170
171
  end
171
172
 
172
- def self.build_element_node(nokogiri_element, preserve_whitespace: false)
173
+ def self.build_element_node(nokogiri_element, preserve_whitespace: false,
174
+ inherited_namespaces: nil)
173
175
  element = Nodes::ElementNode.new(
174
176
  name: nokogiri_element.name,
175
177
  namespace_uri: nokogiri_element.namespace&.href,
176
178
  prefix: nokogiri_element.namespace&.prefix,
177
179
  )
178
180
 
179
- build_namespace_nodes(nokogiri_element, element)
181
+ scope = nokogiri_namespace_scope(nokogiri_element, inherited_namespaces)
182
+ scope.each do |prefix, uri|
183
+ element.add_namespace(Nodes::NamespaceNode.new(
184
+ prefix: prefix,
185
+ uri: uri,
186
+ ))
187
+ end
188
+
180
189
  build_attribute_nodes(nokogiri_element, element)
181
190
 
182
191
  nokogiri_element.children.each do |child|
183
192
  node = build_node_from_nokogiri(child,
184
- preserve_whitespace: preserve_whitespace)
193
+ preserve_whitespace: preserve_whitespace,
194
+ inherited_namespaces: scope)
185
195
  element.add_child(node) if node
186
196
  end
187
197
 
188
198
  element
189
199
  end
190
200
 
191
- def self.build_namespace_nodes(nokogiri_element, element)
192
- namespaces = collect_in_scope_namespaces(nokogiri_element)
193
-
194
- namespaces.each do |prefix, uri|
195
- ns_node = Nodes::NamespaceNode.new(
196
- prefix: prefix,
197
- uri: uri,
198
- )
199
- element.add_namespace(ns_node)
200
- end
201
- end
202
-
203
- def self.collect_in_scope_namespaces(nokogiri_element)
204
- namespaces = {}
205
-
206
- current = nokogiri_element
207
- while current && !current.is_a?(Nokogiri::XML::Document)
208
- if current.is_a?(Nokogiri::XML::Element)
209
- current.namespace_definitions.each do |ns|
210
- prefix = ns.prefix || ""
211
- unless namespaces.key?(prefix)
212
- namespaces[prefix] = ns.href
213
- end
214
- end
215
- end
216
- current = current.parent
201
+ # In-scope namespace bindings: the element's own declarations
202
+ # shadow inherited ones, xml is prebound. The scope is passed down
203
+ # the recursion — one definition fetch per element instead of an
204
+ # ancestor walk per element (O(n) total, not O(n * depth)).
205
+ def self.nokogiri_namespace_scope(nokogiri_element, inherited)
206
+ scope = inherited ? inherited.dup : { "xml" => "http://www.w3.org/XML/1998/namespace" }
207
+ nokogiri_element.namespace_definitions.each do |ns|
208
+ scope[ns.prefix || ""] = ns.href
217
209
  end
218
-
219
- namespaces["xml"] ||= "http://www.w3.org/XML/1998/namespace"
220
-
221
- namespaces
210
+ scope
222
211
  end
223
212
 
224
213
  def self.build_attribute_nodes(nokogiri_element, element)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.