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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3269b76bcc581101e3b7f6219c58fc5010752ab1af4f4bb35b8e505989f08e04
4
- data.tar.gz: 1c255835027897f446de2bb88b175a5b71432636b2a7ab3810480323865a4dac
3
+ metadata.gz: e55a5915424bfa9e3977ed2d9d5207502c42c48eb8b1f48de5406017d8e7cfa5
4
+ data.tar.gz: '01315569d92e95d97e8d466a20da3e26be9db15d876c1062e45d739179399273'
5
5
  SHA512:
6
- metadata.gz: 12d97fd4ae488aee81c5e04e5b55be1336bea7bad60f14fc2481ee9fdd80689edac7dfc3113a6dc65be605a555d388d10e89566a206993c84438d0fcbd9e8d41
7
- data.tar.gz: 1bf50772dde870a02dd80c1d4d686d2d47149b1d4b9210113bed8e2732dec6c48291105ee26969c92c1d46d6f7086931516c0f6110ce868d662cb2bfa1ea2871
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.307 vs
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.27x
664
+ |3.0x
670
665
  |Engine pool-carved parse
671
666
 
672
667
  |serialize
673
- |3.38x
668
+ |2.9x
674
669
  |
675
670
 
676
671
  |XPath
677
- |50x
672
+ |40x
678
673
  |Native compiled-eval seams
679
674
 
680
675
  |walk + read (`.text`, `[]`)
681
- |1.90x
676
+ |2.0x
682
677
  |C klass-mint wrappers + wrapper read memos
683
678
 
684
679
  |warm re-read
685
- |2.10x
680
+ |2.1x
686
681
  |The memo family — zero string allocation per node
687
682
 
688
683
  |build (`add_element`)
689
- |4.24x
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
- |1.73x
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.115"
4
+ VERSION = "0.5.117"
5
5
  end
@@ -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
@@ -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()")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.115
4
+ version: 0.5.117
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.