lutaml-xsd 1.2.112 → 1.2.113
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ef5ebe654a09dce031fef237b193d2f537550b3f6e05e234214fe2c9bba8a21
|
|
4
|
+
data.tar.gz: bde3cb46ee3b74ea6a2812d98b69c73e8ea5ad5f7a89a838350a290a76917eec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df70a1340ca701bebd079dcd7b514f1657c5aa2a9e4117127a3003fdb0a63487aeb44e981da443b40801194e556be881f181d729cced3d0ed8fc07b08191e4f1
|
|
7
|
+
data.tar.gz: 90623814fed971c9c310f00ea3f1de694b624a15d634a0452e263786bdb3b934891023431af787bfe0cfdc2146bef9f9a3ce29f201d86e85401d3304648c68a5
|
data/TODO.conformance.md
CHANGED
|
@@ -120,7 +120,7 @@ pinned commit) is measured via `rake conformance:w3c`:
|
|
|
120
120
|
|
|
121
121
|
| mode | pass-rate |
|
|
122
122
|
|---|---|
|
|
123
|
-
| pipeline |
|
|
123
|
+
| pipeline | 4649/4696 (98.91%) — FIRST FULL-DENOMINATOR MEASURE, all 94 batches in one rake run |
|
|
124
124
|
|
|
125
125
|
(2026-11-02, bundled-stack measurement with the escape,
|
|
126
126
|
hint-following, pattern-alternative, identity-crash, engine-set,
|
|
@@ -144,7 +144,7 @@ lockfile refresh) → 4411 (93.9%) → 4430 (94.3%) → 4435 (94.4%) →
|
|
|
144
144
|
→ 4557 (97.0%) → 4565 (97.2%) → 4569 (97.3%) → 4562 (drift raw) →
|
|
145
145
|
4563 (97.17%, ref-namespace round) → 4573 (97.38%, group-content
|
|
146
146
|
round) → 4578 (97.49%, attribute-prohibition round) → 4585 (97.64%,
|
|
147
|
-
multi-document round) → 4588 (97.7%, type-binding round) → 4592 (97.79%, model-161 ride) → 4611 (98.19%, engine-406 ride) → 4613 (98.23%, temporal-enumeration round) → 4614 (98.25%, simple-type-children round) → 4617 (98.32%, ic-ancestor-scope round) → 4637 (parent-context rounds + chameleon round 1.2.109) → 4637 (nested-type-candidates round, 1.2.110) → 4637 (redefine-cycle round, 1.2.111) → 4644 measured (98.96% of measured, train-adoption round: moxml 0.6.6 + leptris 1.9.418.0), +
|
|
147
|
+
multi-document round) → 4588 (97.7%, type-binding round) → 4592 (97.79%, model-161 ride) → 4611 (98.19%, engine-406 ride) → 4613 (98.23%, temporal-enumeration round) → 4614 (98.25%, simple-type-children round) → 4617 (98.32%, ic-ancestor-scope round) → 4637 (parent-context rounds + chameleon round 1.2.109) → 4637 (nested-type-candidates round, 1.2.110) → 4637 (redefine-cycle round, 1.2.111) → 4644 measured (98.96% of measured, train-adoption round: moxml 0.6.6 + leptris 1.9.418.0) → 4649 (98.91%, quadratic-dispatch round — first FULL-denominator measure, the 5 reZ budget exclusions retired), +688 net over the 1.2.43 baseline. The escapes round (PR #197 — \d→\p{Nd},
|
|
148
148
|
\w/\W/\s to their XSD value spaces) collapses Regex 120→69;
|
|
149
149
|
same-step pattern facets now behave as alternatives and
|
|
150
150
|
whitespace-only text reaches the facets intact (PR #200), Regex
|
|
@@ -612,6 +612,32 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
|
|
|
612
612
|
the RAW validity boolean — expected-INVALID rows reading false
|
|
613
613
|
are PASSES; the first assembly inverted them and manufactured 9
|
|
614
614
|
phantom reZ regressions before the correction.
|
|
615
|
+
- QUADRATIC-DISPATCH ROUND (2026-11-12, release pending): the
|
|
616
|
+
per-rule profile on reZ003v (a trivial `[\w]` pattern over a
|
|
617
|
+
232KB instance of ~65k `<value>` siblings) showed the RULES at
|
|
618
|
+
~3.3s and the DISPATCH at ~100-370s — `same_name_sibling_index`
|
|
619
|
+
scanned the parent's raw children per element (O(N) per child,
|
|
620
|
+
O(N²) per parent) TIMES five category walks, and
|
|
621
|
+
`positional_children` re-walked the parent's particle tree per
|
|
622
|
+
element. THREE cuts, all semantics-preserving: (a) the sibling
|
|
623
|
+
ordinal is now a per-parent identity-keyed map built in ONE
|
|
624
|
+
O(N) pass (running same-name count — identical to the old
|
|
625
|
+
take(position).count reading); (b) the dispatch skips the scan
|
|
626
|
+
when the content model holds at most ONE same-named candidate
|
|
627
|
+
(positional binding only matters for DUPLICATE declarations,
|
|
628
|
+
isDefault079); (c) positional_children memoizes per
|
|
629
|
+
(declaration, name) on the resolver (schema immutable once
|
|
630
|
+
indexed). reZ003v validate 373.6s → 2.94s (127×); rspec 1663
|
|
631
|
+
green and 40s faster; rubocop clean. LEDGER: 4649/4696
|
|
632
|
+
(98.91%) — the FIRST FULL-DENOMINATOR MEASURE of the campaign:
|
|
633
|
+
ALL 94 batches completed in one rake run, the 5 reZ budget
|
|
634
|
+
exclusions RETIRED (reZ003v/005v/005i/006v/006i measured and
|
|
635
|
+
PASSING in-run), and the batch-03000 carry-over convention
|
|
636
|
+
RETIRED (reI003's tax was the same dispatch overhead, not regex
|
|
637
|
+
backtracking — 50/50 fresh). ZERO regressions vs the 1.2.112
|
|
638
|
+
ledger (47 still-failing in both — the standing remainder:
|
|
639
|
+
contested 24, the upstream filings' legs, the parked redesign
|
|
640
|
+
tails).
|
|
615
641
|
- TRAIN ADOPTION REGRESSION — CHARACTER REFERENCES (2026-11-11):
|
|
616
642
|
the 2026-11-10 adoption verdict ("conformance-IDENTICAL") was
|
|
617
643
|
WRONG for one class: moxml 0.6.4 stopped decoding numeric
|
|
@@ -80,8 +80,17 @@ module Lutaml
|
|
|
80
80
|
resolver.resolve(parent.name, parent.namespace_uri)
|
|
81
81
|
candidates = resolver.positional_children(parent_declaration,
|
|
82
82
|
xml_element.name)
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
# The scan only matters when the parent's content model
|
|
84
|
+
# holds DUPLICATE same-named declarations (isDefault079);
|
|
85
|
+
# a sole candidate binds regardless of position — skipping
|
|
86
|
+
# the sibling scan keeps wide documents linear.
|
|
87
|
+
positional = if candidates.size > 1
|
|
88
|
+
candidates[same_name_sibling_index(
|
|
89
|
+
xml_element, parent
|
|
90
|
+
)]
|
|
91
|
+
else
|
|
92
|
+
candidates.first
|
|
93
|
+
end
|
|
85
94
|
# The binding must agree with the child's OWN namespace:
|
|
86
95
|
# an unqualified ref's global namesake never serves a
|
|
87
96
|
# qualified local namesake (particlesQ016).
|
|
@@ -245,21 +254,31 @@ module Lutaml
|
|
|
245
254
|
override && override.value.to_s.split(":").last
|
|
246
255
|
end
|
|
247
256
|
|
|
248
|
-
# The child's
|
|
257
|
+
# The child's ordinal among its same-named siblings — the index
|
|
249
258
|
# the positional binding (duplicate same-named declarations,
|
|
250
|
-
# isDefault079) binds to.
|
|
259
|
+
# isDefault079) binds to. Keyed on the RAW moxml nodes: the
|
|
251
260
|
# wrapper objects are not identity-stable across accessor calls
|
|
252
|
-
# (the IdUniquenessRule lesson).
|
|
261
|
+
# (the IdUniquenessRule lesson). The per-parent ordinal map is
|
|
262
|
+
# memoized — a document of N same-named siblings costs one
|
|
263
|
+
# O(N) pass per parent instead of an O(N) scan per child
|
|
264
|
+
# (reZ003v: 65k siblings made every dispatch quadratic, times
|
|
265
|
+
# five category walks).
|
|
253
266
|
#
|
|
254
267
|
# @return [Integer]
|
|
255
268
|
def same_name_sibling_index(element, parent)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
269
|
+
parent_raw = parent.moxml_element
|
|
270
|
+
cache = (@sibling_ordinals ||= {}.compare_by_identity)
|
|
271
|
+
ordinals = cache[parent_raw]
|
|
272
|
+
if ordinals.nil?
|
|
273
|
+
ordinals = {}.compare_by_identity
|
|
274
|
+
counts = Hash.new(0)
|
|
275
|
+
parent_raw.elements.each do |node|
|
|
276
|
+
ordinals[node] = counts[node.name]
|
|
277
|
+
counts[node.name] += 1
|
|
278
|
+
end
|
|
279
|
+
cache[parent_raw] = ordinals
|
|
259
280
|
end
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
raw_children.take(position).count { |node| node.name == element.name }
|
|
281
|
+
ordinals.fetch(element.moxml_element, 0)
|
|
263
282
|
end
|
|
264
283
|
|
|
265
284
|
# Whether the parent's content model holds a processContents
|
|
@@ -607,17 +607,28 @@ module Lutaml
|
|
|
607
607
|
# @param parent_declaration [Lutaml::Xml::Schema::Xsd::Element, nil]
|
|
608
608
|
# @param local_name [String]
|
|
609
609
|
# @return [Array<Lutaml::Xml::Schema::Xsd::Element>]
|
|
610
|
+
#
|
|
611
|
+
# Memoized per (declaration, local name): the dispatch calls
|
|
612
|
+
# this for every element, and the particle-tree walk cost is
|
|
613
|
+
# constant across elements of the same parent type (the schema
|
|
614
|
+
# is immutable once indexed).
|
|
610
615
|
def positional_children(parent_declaration, local_name)
|
|
616
|
+
key = [parent_declaration.object_id, local_name]
|
|
617
|
+
cache = (@positional_children ||= {})
|
|
618
|
+
cached = cache[key]
|
|
619
|
+
return cached if cached
|
|
620
|
+
|
|
611
621
|
type = parent_declaration&.complex_type ||
|
|
612
622
|
resolve_type(parent_declaration)
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
623
|
+
computed = []
|
|
624
|
+
if type.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
|
|
625
|
+
particles = []
|
|
626
|
+
collect_named_particles(particle_for_type(type), local_name,
|
|
627
|
+
particles, {}.compare_by_identity, 0)
|
|
628
|
+
computed = particles if particles.all? { |p| @namespaces.key?(p) }
|
|
629
|
+
end
|
|
630
|
+
cache[key] = computed
|
|
631
|
+
computed
|
|
621
632
|
end
|
|
622
633
|
|
|
623
634
|
private
|
data/lib/lutaml/xsd/version.rb
CHANGED