moxml 0.5.115 → 0.5.117
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/README.adoc +18 -19
- data/lib/moxml/c14n.rb +7 -0
- data/lib/moxml/node.rb +15 -0
- data/lib/moxml/version.rb +1 -1
- data/spec/moxml/c14n/api_spec.rb +22 -0
- data/spec/moxml/node_spec.rb +13 -0
- 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: e55a5915424bfa9e3977ed2d9d5207502c42c48eb8b1f48de5406017d8e7cfa5
|
|
4
|
+
data.tar.gz: '01315569d92e95d97e8d466a20da3e26be9db15d876c1062e45d739179399273'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5138b1d6a1a60d5b0a6f1a6517599a6b6d05b34cf14266309a0cc9cc3082e332cb62c8cd76477363853beb7b1ae8d7ef6b3833bf17e07ee950ce7f71a68e4bdb
|
|
7
|
+
data.tar.gz: 9b6ba4c742f717ad843eb1bdd08d58957eea374b33988b11dac6d9ece9e8a199739198057c09621c97af94462b329049916f3f0283612941adca7ac199bb73ba
|
data/README.adoc
CHANGED
|
@@ -239,7 +239,7 @@ libleptris has no first-class nodes for them.
|
|
|
239
239
|
| Feature/Operation | Nokogiri | Oga | REXML | LibXML | Ox | HeadedOx | Leptris
|
|
240
240
|
|
|
241
241
|
| *Core Operations*
|
|
242
|
-
|
|
242
|
+
|
|
|
243
243
|
|
|
|
244
244
|
|
|
|
245
245
|
|
|
|
@@ -275,9 +275,8 @@ libleptris has no first-class nodes for them.
|
|
|
275
275
|
| ✅ Full
|
|
276
276
|
|
|
277
277
|
| *Element Operations*
|
|
278
|
-
|
|
279
278
|
|
|
|
280
|
-
|
|
279
|
+
|
|
|
281
280
|
|
|
|
282
281
|
|
|
|
283
282
|
|
|
|
@@ -321,9 +320,8 @@ libleptris has no first-class nodes for them.
|
|
|
321
320
|
| ✅ Full
|
|
322
321
|
|
|
323
322
|
| *Namespace Operations*
|
|
324
|
-
|
|
325
323
|
|
|
|
326
|
-
|
|
324
|
+
|
|
|
327
325
|
|
|
|
328
326
|
|
|
|
329
327
|
|
|
|
@@ -367,9 +365,8 @@ libleptris has no first-class nodes for them.
|
|
|
367
365
|
| ✅ Full
|
|
368
366
|
|
|
369
367
|
| *XPath Queries*
|
|
370
|
-
|
|
371
368
|
|
|
|
372
|
-
|
|
369
|
+
|
|
|
373
370
|
|
|
|
374
371
|
|
|
|
375
372
|
|
|
|
@@ -467,9 +464,8 @@ libleptris has no first-class nodes for them.
|
|
|
467
464
|
| ✅ All 27
|
|
468
465
|
|
|
469
466
|
| *Special Content*
|
|
470
|
-
|
|
471
467
|
|
|
|
472
|
-
|
|
468
|
+
|
|
|
473
469
|
|
|
|
474
470
|
|
|
|
475
471
|
|
|
|
@@ -513,9 +509,8 @@ libleptris has no first-class nodes for them.
|
|
|
513
509
|
| ⚠️ Value-object sidecar^8^
|
|
514
510
|
|
|
515
511
|
| *Performance*
|
|
516
|
-
|
|
517
512
|
|
|
|
518
|
-
|
|
513
|
+
|
|
|
519
514
|
|
|
|
520
515
|
|
|
|
521
516
|
|
|
|
@@ -658,7 +653,7 @@ puts doc.to_xml(indent: 2)
|
|
|
658
653
|
=== Performance versus nokogiri
|
|
659
654
|
|
|
660
655
|
CPU-time medians (1,000-record catalog, 20 iterations) through the
|
|
661
|
-
moxml adapter layer on both sides — moxml + leptris 1.9.
|
|
656
|
+
moxml adapter layer on both sides — moxml + leptris 1.9.314 vs
|
|
662
657
|
moxml + nokogiri:
|
|
663
658
|
|
|
664
659
|
[cols="2,1,4"]
|
|
@@ -666,31 +661,35 @@ moxml + nokogiri:
|
|
|
666
661
|
|Operation |leptris vs nokogiri |Notes
|
|
667
662
|
|
|
668
663
|
|parse
|
|
669
|
-
|3.
|
|
664
|
+
|3.0x
|
|
670
665
|
|Engine pool-carved parse
|
|
671
666
|
|
|
672
667
|
|serialize
|
|
673
|
-
|
|
|
668
|
+
|2.9x
|
|
674
669
|
|
|
|
675
670
|
|
|
676
671
|
|XPath
|
|
677
|
-
|
|
|
672
|
+
|40x
|
|
678
673
|
|Native compiled-eval seams
|
|
679
674
|
|
|
680
675
|
|walk + read (`.text`, `[]`)
|
|
681
|
-
|
|
|
676
|
+
|2.0x
|
|
682
677
|
|C klass-mint wrappers + wrapper read memos
|
|
683
678
|
|
|
684
679
|
|warm re-read
|
|
685
|
-
|2.
|
|
680
|
+
|2.1x
|
|
686
681
|
|The memo family — zero string allocation per node
|
|
687
682
|
|
|
688
683
|
|build (`add_element`)
|
|
689
|
-
|
|
|
684
|
+
|3.7x
|
|
690
685
|
|C-mint construction + bulk attributes
|
|
691
686
|
|
|
687
|
+
|build (Builder DSL)
|
|
688
|
+
|2.1x
|
|
689
|
+
|Markup-accumulating face — one crossing per subtree
|
|
690
|
+
|
|
692
691
|
|attribute pairs
|
|
693
|
-
|
|
|
692
|
+
|parity
|
|
694
693
|
|One C crossing, no Attribute objects
|
|
695
694
|
|===
|
|
696
695
|
|
data/lib/moxml/c14n.rb
CHANGED
|
@@ -37,6 +37,13 @@ module Moxml
|
|
|
37
37
|
# :inclusive10 Canonical XML 1.0 (default; W3C REC-xml-c14n-20010315)
|
|
38
38
|
# :inclusive11 Canonical XML 1.1 (W3C REC-xml-c14n11-20080502)
|
|
39
39
|
# :exclusive10 Exclusive C14N 1.0 (W3C REC-xml-exc-c14n-20020718)
|
|
40
|
+
# Testing helper (TODO.c14n/15): do two XML inputs share one
|
|
41
|
+
# canonical form? Both sides canonicalize inclusively (C14N 1.0,
|
|
42
|
+
# comments dropped) — the default digest shape.
|
|
43
|
+
def self.same_canonical_form?(left, right)
|
|
44
|
+
canonicalize(left) == canonicalize(right)
|
|
45
|
+
end
|
|
46
|
+
|
|
40
47
|
def self.canonicalize(node_or_xml, with_comments: false,
|
|
41
48
|
algorithm: :inclusive10, inclusive_namespaces: [])
|
|
42
49
|
if (native = native_inclusive10(node_or_xml, algorithm, with_comments,
|
data/lib/moxml/node.rb
CHANGED
|
@@ -565,6 +565,11 @@ module Moxml
|
|
|
565
565
|
Moxml::Node.wrap(adapter.duplicate_node(@native), context)
|
|
566
566
|
end
|
|
567
567
|
|
|
568
|
+
# Deliberately identical to #dup: a deep structural copy is the
|
|
569
|
+
# only sensible semantics for XML nodes, and a wrapper carries no
|
|
570
|
+
# frozen state or singleton methods to preserve — so the Ruby
|
|
571
|
+
# clone/dup distinction has nothing to differ on (see
|
|
572
|
+
# TODO.refactor/07, accepted alternative).
|
|
568
573
|
alias clone dup
|
|
569
574
|
|
|
570
575
|
# Returns an XPath expression that uniquely locates this node within
|
|
@@ -638,6 +643,16 @@ module Moxml
|
|
|
638
643
|
add_next_sibling(node)
|
|
639
644
|
end
|
|
640
645
|
|
|
646
|
+
# All sibling nodes excluding self, in document order.
|
|
647
|
+
def siblings
|
|
648
|
+
return NodeSet.new([], context) unless parent
|
|
649
|
+
|
|
650
|
+
NodeSet.new(
|
|
651
|
+
parent.children.reject { |c| c.equal?(self) }.map(&:native),
|
|
652
|
+
context,
|
|
653
|
+
)
|
|
654
|
+
end
|
|
655
|
+
|
|
641
656
|
def blank?
|
|
642
657
|
text.strip.empty?
|
|
643
658
|
end
|
data/lib/moxml/version.rb
CHANGED
data/spec/moxml/c14n/api_spec.rb
CHANGED
|
@@ -114,4 +114,26 @@ RSpec.describe "Moxml::C14n API" do
|
|
|
114
114
|
.to eq(%(a"b	c
d))
|
|
115
115
|
end
|
|
116
116
|
end
|
|
117
|
+
|
|
118
|
+
describe ".same_canonical_form?" do
|
|
119
|
+
let(:cmp_ctx) { Moxml.new(:leptris) }
|
|
120
|
+
|
|
121
|
+
it "is true for documents differing only in canonical form" do
|
|
122
|
+
a = cmp_ctx.parse('<r xmlns="urn:x"><a k="1">t</a></r>')
|
|
123
|
+
b = cmp_ctx.parse('<r xmlns="urn:x"><a k="1">t</a></r>')
|
|
124
|
+
expect(Moxml::C14n.same_canonical_form?(a, b)).to be(true)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "is false across a semantic difference" do
|
|
128
|
+
a = cmp_ctx.parse('<r xmlns="urn:x"><a k="1">t</a></r>')
|
|
129
|
+
b = cmp_ctx.parse('<r><a k="1">t</a></r>')
|
|
130
|
+
expect(Moxml::C14n.same_canonical_form?(a, b)).to be(false)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "accepts raw XML strings" do
|
|
134
|
+
expect(
|
|
135
|
+
Moxml::C14n.same_canonical_form?("<r><a/></r>", "<r><a/></r>"),
|
|
136
|
+
).to be(true)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
117
139
|
end
|
data/spec/moxml/node_spec.rb
CHANGED
|
@@ -168,6 +168,19 @@ RSpec.describe Moxml::Node do
|
|
|
168
168
|
end
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
+
it "lists siblings excluding self, in document order" do
|
|
172
|
+
doc = Moxml.new(:leptris).parse("<r><a/><b/><c/></r>")
|
|
173
|
+
b = doc.at("//b")
|
|
174
|
+
siblings = b.siblings
|
|
175
|
+
expect(siblings).to be_a(Moxml::NodeSet)
|
|
176
|
+
expect(siblings.map(&:name)).to eq(%w[a c])
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "returns an empty sibling set for a rootless node" do
|
|
180
|
+
doc = Moxml.new(:leptris).parse("<r/>")
|
|
181
|
+
expect(doc.root.siblings.to_a).to be_empty
|
|
182
|
+
end
|
|
183
|
+
|
|
171
184
|
it "locates non-element nodes through typed node tests" do
|
|
172
185
|
text = doc.root.children.first.children.first
|
|
173
186
|
expect(text.path).to end_with("/text()")
|