canon 0.3.0 → 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: 0d1f4de27225e068e0bc1a00b2b7b2d980847bf9027a21f042de148aae65926e
4
- data.tar.gz: 4561eaa1efb9abcd541ec8da05f2e33df11859c35d6e5fe3f5fee9fa9d22af3d
3
+ metadata.gz: b000e9e89684d66d4f037a950a2121a88717dd6c72d975648742f32b5a83fb9f
4
+ data.tar.gz: c5e8b5ecfdcb8435559be3e6c940e8e8bec99202054b90fa857f9e3afd3097e2
5
5
  SHA512:
6
- metadata.gz: ee29ec80689f0c53771017dca13d48ba4c3162db98f0e3605c3198148035cd564d818b8e4c08728608ef3abd055231d82850f79f933d2206ec4a36d488c6faa6
7
- data.tar.gz: 37ae2bd7e928265b8c54e4025ae73d7e8761ce6e28ee2933e005129bd218d7003a5d547103bba140e11e829ef4d45aa7ef41768766b302f6608814f08fb74983
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.0"
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)
@@ -261,7 +250,7 @@ preserve_whitespace: false)
261
250
  # --- Moxml path ---
262
251
 
263
252
  def self.from_moxml_xml(xml_string, preserve_whitespace:)
264
- doc = Canon::XmlParsing.parse(xml_string)
253
+ doc = Canon::XmlParsing.moxml_context.parse(xml_string, readonly: true)
265
254
  check_moxml_relative_namespace_uris(doc)
266
255
  result = build_from_moxml(doc, preserve_whitespace: preserve_whitespace)
267
256
  # Canon owns this document's full lifecycle: the canon tree holds
@@ -390,11 +379,11 @@ preserve_whitespace: false)
390
379
  ))
391
380
  end
392
381
 
393
- # Adopt completed children (they stack in reverse: unshift
394
- # restores document order).
382
+ # Adopt completed children: they pop in reverse order; reversing
383
+ # once is O(n) (unshift per child would be O(n^2) on wide trees).
395
384
  children = []
396
- children.unshift(frames.pop[1]) while frames.any? && frames.last[0] > record[:depth]
397
- children.each { |child| element.add_child(child) }
385
+ children << frames.pop[1] while frames.any? && frames.last[0] > record[:depth]
386
+ children.reverse_each { |child| element.add_child(child) }
398
387
 
399
388
  own_namespaces[element] = record[:namespaces]
400
389
  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.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.