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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19a629abe9ac053899019037981e12e3c502bbbd17c0f6456787190dd52b7713
4
- data.tar.gz: a403d2c8184c297216afffa96ff9f236e656f6027d1e8595f9afa794cb5362a6
3
+ metadata.gz: 81113f3b383bfa48715846b5c216add5e652c0c7b70e587d6182b95633b1a49f
4
+ data.tar.gz: ffea6cdeeed2c00c883dbc64b7e7f6edd614ee9553311ab552a765f853070726
5
5
  SHA512:
6
- metadata.gz: 76a79f3d5e6ff50291fe0d8e9f29cd53325ae38b7a8eb679ef758829cac8069bb6f3911f4cf2c7739522db3cfe80f6514107c88813316f849ab2cd4e49e5ab74
7
- data.tar.gz: 4f44e60f03e3145daee06ec180e6a4fdbbd0d03618104641c19991989a8d028f23d5a2f4209adbfb05fa80cfb10dc0a6e10450e8debade2208debdb35e93dd49
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 | 4614/4696 (98.25%) |
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), +653 net over the 1.2.43 baseline. The escapes round (PR #197 — \d→\p{Nd},
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
- (owner_ns && repository.resolve_global(local, owner_ns)) ||
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
- collected = {}
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
- (owner_ns && repository&.resolve_global(local, owner_ns)) ||
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.92"
5
+ VERSION = "1.2.94"
6
6
  end
7
7
  end
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.92
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-05 00:00:00.000000000 Z
11
+ date: 2026-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid