lutaml-xsd 1.2.92 → 1.2.94
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/TODO.conformance.md +17 -2
- data/lib/lutaml/xsd/validation/rules/content_model_validation_rule.rb +6 -1
- data/lib/lutaml/xsd/validation/rules/identity_constraints_rule.rb +6 -1
- data/lib/lutaml/xsd/validation/schema_definition_resolver.rb +96 -0
- data/lib/lutaml/xsd/validation/validation_rule.rb +7 -2
- data/lib/lutaml/xsd/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 81113f3b383bfa48715846b5c216add5e652c0c7b70e587d6182b95633b1a49f
|
|
4
|
+
data.tar.gz: ffea6cdeeed2c00c883dbc64b7e7f6edd614ee9553311ab552a765f853070726
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36438665084751f73c476788ce845587526c6f043233542aa214e73a60561b79d6a0b34fe637ace8978b0a4efccbfcbc597be31cc3de98418c6a8c5c0cbdcd40
|
|
7
|
+
data.tar.gz: 95f5077418bd7a008c394a9d559029ca7d7f31947b0be1ecb3dd09967bf6fe804375f87b26dca50b79b612d35049f7d4c401be9bb7c45a45a4aff918f0cb152e
|
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 | 4617/4696 (98.32%) |
|
|
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), +
|
|
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), +656 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
|
|
@@ -528,6 +528,21 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
|
|
|
528
528
|
407 wins ride again when #47 and #529 land. NET: no score
|
|
529
529
|
change; the pin protects the register.
|
|
530
530
|
|
|
531
|
+
- IC ANCESTOR-SCOPE ROUND (2026-11-05): +1 IC (idZ008; suite
|
|
532
|
+
4614->4617 = 98.32% with the prefix-resolution and
|
|
533
|
+
temporal-enumeration riders on main, zero regressions, rspec
|
|
534
|
+
green). A keyref whose `refer` names a key declared on an
|
|
535
|
+
ANCESTOR element resolved against an empty table — the
|
|
536
|
+
collected-keys map reset per element (idZ008: the key KeyAAA on
|
|
537
|
+
A, the keyref QQQ on the descendant A2, selector "."). The map
|
|
538
|
+
now accumulates across the walk; instance document order
|
|
539
|
+
guarantees ancestors process before descendants. The other five
|
|
540
|
+
IC singletons (idK012, idZ010/011/012/015) have DIFFERENT roots
|
|
541
|
+
(cross-namespace keyrefs, IDREF defaults) — next rounds. NOTE:
|
|
542
|
+
the PREFIX-RESOLUTION round (+1, particlesQ032 via the 1131
|
|
543
|
+
xmlns-declarations retention in lutaml-model 0.8.167 — pinned)
|
|
544
|
+
is also on main; the score line carries both.
|
|
545
|
+
|
|
531
546
|
- SIMPLE-TYPE-CHILDREN ROUND (2026-11-05, third attempt — the first
|
|
532
547
|
two regressed 15 at scale): +1 DataTypes (dtZ86723; suite
|
|
533
548
|
4613->4614 = 98.25%, zero regressions, rspec green). A simple
|
|
@@ -604,7 +604,12 @@ module Lutaml
|
|
|
604
604
|
return nil unless repository
|
|
605
605
|
|
|
606
606
|
local = particle.ref.to_s.split(":").last
|
|
607
|
-
|
|
607
|
+
exact_ns = repository&.ref_namespace(particle)
|
|
608
|
+
exact_target =
|
|
609
|
+
if exact_ns || owner_ns
|
|
610
|
+
repository.resolve_global(local, exact_ns || owner_ns)
|
|
611
|
+
end
|
|
612
|
+
exact_target ||
|
|
608
613
|
repository.resolve(local, child.namespace_uri) ||
|
|
609
614
|
repository.resolve(local, nil)
|
|
610
615
|
end
|
|
@@ -52,7 +52,12 @@ module Lutaml
|
|
|
52
52
|
# schema's target namespace (the suite's single-namespace shapes).
|
|
53
53
|
target_ns = repository&.target_namespace_for(schema_element).to_s
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
# Key tables accumulate across the walk: a keyref whose
|
|
56
|
+
# `refer` names a key declared on an ANCESTOR resolves
|
|
57
|
+
# against the ancestor's rows (idZ008 — the key on A, the
|
|
58
|
+
# keyref on the descendant A2). Instance document order
|
|
59
|
+
# guarantees ancestors are processed before descendants.
|
|
60
|
+
collected = @collected_keys ||= {}
|
|
56
61
|
|
|
57
62
|
Array(schema_element.key).each do |constraint|
|
|
58
63
|
evaluated_constraints << constraint.name.to_s if constraint.name
|
|
@@ -65,6 +65,11 @@ module Lutaml
|
|
|
65
65
|
# redefined enumeration). The facet walk never recurses into
|
|
66
66
|
# named bases, so the body's base reference terminates here.
|
|
67
67
|
@redefined_simple_bodies = {}
|
|
68
|
+
# Exact namespaces for PREFIXED ref particles, from the
|
|
69
|
+
# owning schema's xmlns declarations (lutaml-model 0.8.167
|
|
70
|
+
# retains them — #1131). The prefix IS the semantics: a ref
|
|
71
|
+
# names the declaration its prefix binds, exactly.
|
|
72
|
+
@ref_namespaces = {}.compare_by_identity
|
|
68
73
|
@elements = index_elements
|
|
69
74
|
end
|
|
70
75
|
|
|
@@ -597,6 +602,96 @@ module Lutaml
|
|
|
597
602
|
schema.to_xml]
|
|
598
603
|
end
|
|
599
604
|
|
|
605
|
+
# Exact namespaces for every PREFIXED ref particle in the
|
|
606
|
+
# document, resolved through the document's own xmlns
|
|
607
|
+
# declarations (lutaml-model 0.8.167+ retains them — #1131).
|
|
608
|
+
# The prefix IS the semantics: a ref names the declaration its
|
|
609
|
+
# prefix binds. Documents parsed by older lutaml-models carry
|
|
610
|
+
# no declarations and simply contribute nothing.
|
|
611
|
+
#
|
|
612
|
+
# @return [void]
|
|
613
|
+
def register_ref_namespaces(schema)
|
|
614
|
+
declarations = schema.respond_to?(:xmlns_declarations) &&
|
|
615
|
+
schema.xmlns_declarations
|
|
616
|
+
return unless declarations.is_a?(Hash)
|
|
617
|
+
|
|
618
|
+
descend = lambda do |node, depth|
|
|
619
|
+
return if depth > 10
|
|
620
|
+
return unless node
|
|
621
|
+
|
|
622
|
+
if node.is_a?(Array)
|
|
623
|
+
node.each { |child| descend.call(child, depth) }
|
|
624
|
+
return
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
if node.is_a?(Lutaml::Xml::Schema::Xsd::Element)
|
|
628
|
+
ref = node.ref.to_s
|
|
629
|
+
if ref.include?(":")
|
|
630
|
+
uri = declarations[ref.split(":").first]
|
|
631
|
+
@ref_namespaces[node] = uri if uri
|
|
632
|
+
end
|
|
633
|
+
return
|
|
634
|
+
end
|
|
635
|
+
if node.is_a?(Lutaml::Xml::Schema::Xsd::Group)
|
|
636
|
+
declaration =
|
|
637
|
+
resolve_group((node.ref || node.name).to_s.split(":").last)
|
|
638
|
+
container = declaration &&
|
|
639
|
+
(Array(declaration.sequence).first ||
|
|
640
|
+
Array(declaration.choice).first ||
|
|
641
|
+
Array(declaration.all).first)
|
|
642
|
+
descend.call(container, depth + 1) if container
|
|
643
|
+
return
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
containers = {
|
|
647
|
+
Lutaml::Xml::Schema::Xsd::Schema =>
|
|
648
|
+
%i[element complex_type simple_type attribute
|
|
649
|
+
attribute_group group import include redefine],
|
|
650
|
+
Lutaml::Xml::Schema::Xsd::ComplexType =>
|
|
651
|
+
%i[sequence choice all group complex_content
|
|
652
|
+
simple_content],
|
|
653
|
+
Lutaml::Xml::Schema::Xsd::ExtensionComplexContent =>
|
|
654
|
+
%i[sequence choice all group],
|
|
655
|
+
Lutaml::Xml::Schema::Xsd::RestrictionComplexContent =>
|
|
656
|
+
%i[sequence choice all group],
|
|
657
|
+
Lutaml::Xml::Schema::Xsd::ComplexContent =>
|
|
658
|
+
%i[extension restriction],
|
|
659
|
+
Lutaml::Xml::Schema::Xsd::SimpleContent =>
|
|
660
|
+
%i[extension restriction],
|
|
661
|
+
Lutaml::Xml::Schema::Xsd::Sequence =>
|
|
662
|
+
%i[element any sequence choice group],
|
|
663
|
+
Lutaml::Xsd::Sequence =>
|
|
664
|
+
%i[element any sequence choice group],
|
|
665
|
+
Lutaml::Xml::Schema::Xsd::Choice =>
|
|
666
|
+
%i[element any sequence choice group],
|
|
667
|
+
Lutaml::Xsd::Choice =>
|
|
668
|
+
%i[element any sequence choice group],
|
|
669
|
+
Lutaml::Xml::Schema::Xsd::All => %i[element],
|
|
670
|
+
Lutaml::Xsd::All => %i[element],
|
|
671
|
+
}[node.class]
|
|
672
|
+
return unless containers
|
|
673
|
+
|
|
674
|
+
containers.each do |accessor|
|
|
675
|
+
Array(node.public_send(accessor)).each do |child|
|
|
676
|
+
descend.call(child, depth + 1)
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
descend.call(schema, 0)
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
public
|
|
684
|
+
|
|
685
|
+
# The exact namespace a PREFIXED ref particle names, when the
|
|
686
|
+
# owning document's prefix map is retained (0.8.167+); nil
|
|
687
|
+
# otherwise (the owner-namespace heuristic applies).
|
|
688
|
+
#
|
|
689
|
+
# @param particle [Object]
|
|
690
|
+
# @return [String, nil]
|
|
691
|
+
def ref_namespace(particle)
|
|
692
|
+
@ref_namespaces[particle]
|
|
693
|
+
end
|
|
694
|
+
|
|
600
695
|
def index_schema(index, schema, held_signatures = [],
|
|
601
696
|
chameleon_namespace = nil,
|
|
602
697
|
chameleon_includer = nil)
|
|
@@ -607,6 +702,7 @@ module Lutaml
|
|
|
607
702
|
chameleon = raw_namespace.to_s.empty? && chameleon_namespace
|
|
608
703
|
namespace = chameleon ? chameleon_namespace : raw_namespace
|
|
609
704
|
defaults_schema = chameleon ? chameleon_includer : schema
|
|
705
|
+
register_ref_namespaces(schema)
|
|
610
706
|
Array(schema.element).each do |element|
|
|
611
707
|
index_element(index, element, namespace, :top, defaults_schema)
|
|
612
708
|
# A global element's INLINE complexType carries local
|
|
@@ -254,9 +254,14 @@ module Lutaml
|
|
|
254
254
|
# matches no-namespace declarations, and a hint-loaded
|
|
255
255
|
# document can supply a foreign namesake. The owner probe
|
|
256
256
|
# is GLOBAL-only: a ref names a global declaration, and an
|
|
257
|
-
# inline namesake must not satisfy it.
|
|
257
|
+
# inline namesake must not satisfy it. A RETAINED prefix
|
|
258
|
+
# map (lutaml-model 0.8.167+, #1131) resolves the ref
|
|
259
|
+
# EXACTLY — the prefix is the semantics.
|
|
260
|
+
exact_ns = repository&.ref_namespace(particle)
|
|
258
261
|
declaration =
|
|
259
|
-
|
|
262
|
+
if exact_ns || owner_ns
|
|
263
|
+
repository&.resolve_global(local, exact_ns || owner_ns)
|
|
264
|
+
end ||
|
|
260
265
|
repository&.resolve(local, child.namespace_uri) ||
|
|
261
266
|
repository&.resolve(local, nil)
|
|
262
267
|
# An unresolvable ref (particlesQ032: a no-namespace document
|
data/lib/lutaml/xsd/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lutaml-xsd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.94
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-11-
|
|
11
|
+
date: 2026-11-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: liquid
|