canon 0.3.3 → 0.3.4
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 +4 -4
- data/lib/canon/version.rb +1 -1
- data/lib/canon/xml/data_model.rb +56 -49
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 53a9382cf5977e8e1b65a847cd11f9f2c61a162c3913a64588e4d48c71cfbf94
|
|
4
|
+
data.tar.gz: 851f0227e56cffdd225fce23ec32b78b3b44f43e08137a39572a2db237d94aaf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67710ade1d18f99c23e4477540303f45867d145c7f92df59f2f1277cf442c576eca2a3d8562cb92972f56d80dbe111e6104d28353cb7c5091d690490605772ff
|
|
7
|
+
data.tar.gz: e8d2783baa8fba878cb3cbb7a602dff3563f23dfb15df95ca5c24c075475d53c8319f2579bf3ce3c533e1989b1c75b91b72913c57c30279278a59de68202aef0
|
data/lib/canon/version.rb
CHANGED
data/lib/canon/xml/data_model.rb
CHANGED
|
@@ -126,28 +126,49 @@ module Canon
|
|
|
126
126
|
end
|
|
127
127
|
end
|
|
128
128
|
|
|
129
|
+
# --- Shared construction kernels (identical semantics per engine) ---
|
|
130
|
+
|
|
131
|
+
# Attach document-level children (prolog/epilog PIs, comments,
|
|
132
|
+
# document-level text) to the canon root, in document order,
|
|
133
|
+
# skipping the document element and the doctype. `converter`
|
|
134
|
+
# converts one engine child to a canon node (or nil).
|
|
135
|
+
def self.add_document_children(root, children, document_element,
|
|
136
|
+
skip_types, converter)
|
|
137
|
+
children.each do |child|
|
|
138
|
+
next if child.equal?(document_element)
|
|
139
|
+
next if skip_types.any? { |type| child.is_a?(type) }
|
|
140
|
+
|
|
141
|
+
node = converter.call(child)
|
|
142
|
+
root.add_child(node) if node
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# In-scope namespace bindings: the element's own declarations
|
|
147
|
+
# shadow inherited ones; xml is prebound at the base. Declaration
|
|
148
|
+
# pairs are [prefix-or-nil, uri]; nil and "" both mean the default
|
|
149
|
+
# namespace.
|
|
150
|
+
def self.merge_namespace_scope(inherited, declaration_pairs)
|
|
151
|
+
scope = inherited ? inherited.dup : { "xml" => "http://www.w3.org/XML/1998/namespace" }
|
|
152
|
+
declaration_pairs.each do |prefix, uri|
|
|
153
|
+
scope[prefix || ""] = uri
|
|
154
|
+
end
|
|
155
|
+
scope
|
|
156
|
+
end
|
|
157
|
+
|
|
129
158
|
def self.build_from_nokogiri(nokogiri_doc, preserve_whitespace: false)
|
|
130
159
|
root = Nodes::RootNode.new
|
|
131
160
|
|
|
161
|
+
converter = ->(child) { build_node_from_nokogiri(child, preserve_whitespace: preserve_whitespace) }
|
|
162
|
+
skip_types = defined?(Nokogiri) ? [Nokogiri::XML::DTD] : []
|
|
163
|
+
|
|
132
164
|
if nokogiri_doc.is_a?(Nokogiri::XML::Document) && nokogiri_doc.root
|
|
133
165
|
root.add_child(build_element_node(nokogiri_doc.root,
|
|
134
166
|
preserve_whitespace: preserve_whitespace))
|
|
135
|
-
nokogiri_doc.children.
|
|
136
|
-
|
|
137
|
-
next if child.is_a?(Nokogiri::XML::DTD)
|
|
138
|
-
|
|
139
|
-
node = build_node_from_nokogiri(child,
|
|
140
|
-
preserve_whitespace: preserve_whitespace)
|
|
141
|
-
root.add_child(node) if node
|
|
142
|
-
end
|
|
167
|
+
add_document_children(root, nokogiri_doc.children, nokogiri_doc.root,
|
|
168
|
+
skip_types, converter)
|
|
143
169
|
else
|
|
144
|
-
nokogiri_doc.children
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
node = build_node_from_nokogiri(child,
|
|
148
|
-
preserve_whitespace: preserve_whitespace)
|
|
149
|
-
root.add_child(node) if node
|
|
150
|
-
end
|
|
170
|
+
add_document_children(root, nokogiri_doc.children, nil,
|
|
171
|
+
skip_types, converter)
|
|
151
172
|
end
|
|
152
173
|
|
|
153
174
|
root
|
|
@@ -198,16 +219,14 @@ inherited_namespaces: nil)
|
|
|
198
219
|
element
|
|
199
220
|
end
|
|
200
221
|
|
|
201
|
-
# In-scope
|
|
202
|
-
# shadow inherited ones, xml is prebound. The scope is passed down
|
|
222
|
+
# In-scope bindings via the shared kernel; the scope is passed down
|
|
203
223
|
# the recursion — one definition fetch per element instead of an
|
|
204
224
|
# ancestor walk per element (O(n) total, not O(n * depth)).
|
|
205
225
|
def self.nokogiri_namespace_scope(nokogiri_element, inherited)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
scope
|
|
226
|
+
merge_namespace_scope(inherited,
|
|
227
|
+
nokogiri_element.namespace_definitions.map do |ns|
|
|
228
|
+
[ns.prefix, ns.href]
|
|
229
|
+
end)
|
|
211
230
|
end
|
|
212
231
|
|
|
213
232
|
def self.build_attribute_nodes(nokogiri_element, element)
|
|
@@ -283,26 +302,18 @@ inherited_namespaces: nil)
|
|
|
283
302
|
def self.build_from_moxml(moxml_doc, preserve_whitespace: false)
|
|
284
303
|
root = Nodes::RootNode.new
|
|
285
304
|
|
|
305
|
+
converter = ->(child) { build_moxml_node(child, preserve_whitespace: preserve_whitespace) }
|
|
306
|
+
skip_types = [Moxml::Doctype]
|
|
307
|
+
|
|
286
308
|
if moxml_doc.is_a?(Moxml::Document) && moxml_doc.root
|
|
287
309
|
element = build_moxml_subtree_from_records(moxml_doc.root,
|
|
288
310
|
preserve_whitespace: preserve_whitespace)
|
|
289
311
|
root.add_child(element) if element
|
|
290
|
-
moxml_doc.children.
|
|
291
|
-
|
|
292
|
-
next if child.is_a?(Moxml::Doctype)
|
|
293
|
-
|
|
294
|
-
node = build_moxml_node(child,
|
|
295
|
-
preserve_whitespace: preserve_whitespace)
|
|
296
|
-
root.add_child(node) if node
|
|
297
|
-
end
|
|
312
|
+
add_document_children(root, moxml_doc.children, moxml_doc.root,
|
|
313
|
+
skip_types, converter)
|
|
298
314
|
else
|
|
299
|
-
moxml_doc.children
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
node = build_moxml_node(child,
|
|
303
|
-
preserve_whitespace: preserve_whitespace)
|
|
304
|
-
root.add_child(node) if node
|
|
305
|
-
end
|
|
315
|
+
add_document_children(root, moxml_doc.children, nil,
|
|
316
|
+
skip_types, converter)
|
|
306
317
|
end
|
|
307
318
|
|
|
308
319
|
root
|
|
@@ -401,14 +412,11 @@ preserve_whitespace: false)
|
|
|
401
412
|
Nodes::TextNode.new(value: content, original: content)
|
|
402
413
|
end
|
|
403
414
|
|
|
404
|
-
# Expand each element's own declarations to in-scope bindings
|
|
405
|
-
# the
|
|
406
|
-
#
|
|
415
|
+
# Expand each element's own declarations to in-scope bindings via
|
|
416
|
+
# the shared kernel. Scope flows down the canon tree — no engine
|
|
417
|
+
# calls.
|
|
407
418
|
def self.assign_moxml_namespace_scopes(element, inherited, own_namespaces)
|
|
408
|
-
scope = inherited.
|
|
409
|
-
own_namespaces[element].to_a.each do |prefix, uri|
|
|
410
|
-
scope[prefix || ""] = uri
|
|
411
|
-
end
|
|
419
|
+
scope = merge_namespace_scope(inherited, own_namespaces[element].to_a)
|
|
412
420
|
|
|
413
421
|
scope.each do |prefix, uri|
|
|
414
422
|
element.add_namespace(Nodes::NamespaceNode.new(
|
|
@@ -474,11 +482,10 @@ inherited_namespaces: nil)
|
|
|
474
482
|
# of an ancestor walk through the adapter layer (the Nokogiri
|
|
475
483
|
# collector walks ancestors because those calls are cheap there).
|
|
476
484
|
def self.moxml_namespace_scope(moxml_element, inherited)
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
scope
|
|
485
|
+
merge_namespace_scope(inherited,
|
|
486
|
+
moxml_element.namespace_definitions.map do |decl|
|
|
487
|
+
[decl.prefix, decl.uri]
|
|
488
|
+
end)
|
|
482
489
|
end
|
|
483
490
|
|
|
484
491
|
def self.build_moxml_attribute_nodes(moxml_element, element)
|