lutaml-xsd 1.2.93 → 1.2.95

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: 6ad03adc4f701faa3d3c132f2704c5dc7e01033e7403750352156cbe7a2333a9
4
- data.tar.gz: b861d33acb72791876fee6e23ba03bc94a662d570b127056803a75de319a2a4a
3
+ metadata.gz: a752804ef8cfcbbe98845ffcfcbd8830d2c37020d392d34524795f645351cef9
4
+ data.tar.gz: 467cd19ffcc587cbdc4007e614b02f2f299a26917c684e997138fa5116686a7b
5
5
  SHA512:
6
- metadata.gz: 1d64f1ba11d11333972f2cbdbe32c083d423effecefea95b3aca7b99200c0edc314a0861502129ec0a7f58c77a0e7e34474473f2600fd91e6314d25fb83c2949
7
- data.tar.gz: 3e1f6cfbda1193da0844c8e25c6579503c1ceab084acb5d00674e1682c344326167ff00e5f07881655c898a21fed46f9c0e316174a63d3f4491341085cf4126a
6
+ metadata.gz: 904b2740eaa42225aa419c6a27586cc115fbcba3efaa4e4fe987b979f7139bd00e5e96007f094f65b5631a8383bdd12d0e50eaef82482733662d2dcda8658507
7
+ data.tar.gz: 545c68eb6ce9cda1d4b834d3bf608974d3da82e774fee7465918ba39d5c2d7183892c0a314c3314d15f68e8f20a6af27e264fb752f5023008db7a5cfa84be512
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
@@ -527,6 +527,47 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
527
527
  (98.28% restored, zero regressions vs the 406 baseline). The
528
528
  407 wins ride again when #47 and #529 land. NET: no score
529
529
  change; the pin protects the register.
530
+ - NON-SIMPLE-FIELD ROUND (2026-11-07): +2 IC (idK012, idZ010; suite
531
+ 4617->4619 = 98.36%, zero regressions, rspec green). An identity
532
+ field takes a value only from a SIMPLE-typed node: a field hitting
533
+ an element with element children (idK012's pid, complexContent
534
+ restriction of anyType) or one DECLARED non-simple — complex
535
+ content, or xsd:anyType as the typeless-local default (idZ010's
536
+ A3/A22, the cross-namespace import shape) — previously contributed
537
+ its concatenated text as a clean row. The rule consults the field's
538
+ declaration via SchemaDefinitionResolver#field_declaration_simple:
539
+ the IC owner's content model descends the raw selector path, the
540
+ selector element's own type descends the raw field path (base
541
+ chains included; refs resolve to the global declaration). THREE
542
+ guards keep it sound: a resolvable xsi:type override governs the
543
+ INSTANCE value space (idF-class overrides stay simple, idL090
544
+ decimal/string fields untouched); unresolvable descents yield nil
545
+ = no determination (the lenient path is untouched); unresolvable
546
+ named types are simple only when builtin-prefixed. LESSON: the
547
+ tri-state verdicts live in NON-predicate methods — rubocop -A
548
+ rewrites `return nil` guards in `?`-methods to `return false`,
549
+ which silently hardened the lenient path twice before the probes
550
+ caught it. The remaining three IC singletons have DIFFERENT roots
551
+ (next rounds): idZ011 (schema-side xs:ID value-constraint
552
+ prohibition, §3.2.6), idZ012 (IDREFS default "abc" references no
553
+ ID), idZ015 (a skip-wildcard-governed attribute supplies no IC
554
+ field value).
555
+
556
+
557
+ - IC ANCESTOR-SCOPE ROUND (2026-11-05): +1 IC (idZ008; suite
558
+ 4614->4617 = 98.32% with the prefix-resolution and
559
+ temporal-enumeration riders on main, zero regressions, rspec
560
+ green). A keyref whose `refer` names a key declared on an
561
+ ANCESTOR element resolved against an empty table — the
562
+ collected-keys map reset per element (idZ008: the key KeyAAA on
563
+ A, the keyref QQQ on the descendant A2, selector "."). The map
564
+ now accumulates across the walk; instance document order
565
+ guarantees ancestors process before descendants. The other five
566
+ IC singletons (idK012, idZ010/011/012/015) have DIFFERENT roots
567
+ (cross-namespace keyrefs, IDREF defaults) — next rounds. NOTE:
568
+ the PREFIX-RESOLUTION round (+1, particlesQ032 via the 1131
569
+ xmlns-declarations retention in lutaml-model 0.8.167 — pinned)
570
+ is also on main; the score line carries both.
530
571
 
531
572
  - SIMPLE-TYPE-CHILDREN ROUND (2026-11-05, third attempt — the first
532
573
  two regressed 15 at scale): +1 DataTypes (dtZ86723; suite
@@ -52,12 +52,18 @@ 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
59
64
  values = collect_values(xml_element, constraint, collector,
60
- repository, target_ns, :key)
65
+ repository, target_ns, :key,
66
+ schema_element)
61
67
  report_duplicates(collector, xml_element, constraint, values,
62
68
  "duplicate_key_violation")
63
69
  collected[constraint.name] = values if constraint.name
@@ -66,7 +72,8 @@ module Lutaml
66
72
  Array(schema_element.unique).each do |constraint|
67
73
  evaluated_constraints << constraint.name.to_s if constraint.name
68
74
  values = collect_values(xml_element, constraint, collector,
69
- repository, target_ns, :unique)
75
+ repository, target_ns, :unique,
76
+ schema_element)
70
77
  report_duplicates(collector, xml_element, constraint, values,
71
78
  "duplicate_unique_violation")
72
79
  collected[constraint.name] = values if constraint.name
@@ -78,7 +85,8 @@ module Lutaml
78
85
  next if referred.nil?
79
86
 
80
87
  collect_values(xml_element, constraint, collector,
81
- repository, target_ns, :keyref).each do |value|
88
+ repository, target_ns, :keyref,
89
+ schema_element).each do |value|
82
90
  next if referred.include?(value)
83
91
 
84
92
  report_error(
@@ -102,24 +110,53 @@ module Lutaml
102
110
 
103
111
  private
104
112
 
113
+ # Field values (and violation flags) for ONE selector-matched
114
+ # node: per field, the supply value, the node's text/attr
115
+ # value, or a non-simple verdict.
116
+ #
117
+ # @return [Array(Array, Boolean, Boolean)] [values, ambiguous,
118
+ # non_simple]
119
+ def evaluate_field_row(node, fields, raws, constraint,
120
+ owner_element, repository)
121
+ values = []
122
+ ambiguous = false
123
+ non_simple = false
124
+ fields.each_with_index do |field, index|
125
+ matched = field_nodes(node, field)
126
+ # A field evaluating to a node-set with more than one
127
+ # member violates the constraint (XSD 1.0 §3.11.4).
128
+ ambiguous = true if matched.size > 1
129
+ values << if matched.first.nil?
130
+ field_supply_value(node, field, repository)
131
+ elsif matched.first.is_a?(Moxml::Element) &&
132
+ field_node_non_simple?(
133
+ matched.first, constraint, raws[index],
134
+ owner_element, repository
135
+ )
136
+ # An element field hitting an element with
137
+ # ELEMENT children (complex content), or one
138
+ # DECLARED non-simple (complex content or
139
+ # xsd:anyType — the typeless default), supplies
140
+ # no identity value: the field "does evaluate
141
+ # to a node of non-simple type" (idK012/idZ010).
142
+ non_simple = true
143
+ nil
144
+ else
145
+ field_node_value(matched.first)
146
+ end
147
+ end
148
+ [values, ambiguous, non_simple]
149
+ end
150
+
105
151
  def collect_values(xml_element, constraint, collector, repository,
106
- target_namespace, kind)
152
+ target_namespace, kind, owner_element)
107
153
  fields = field_xpaths(constraint, target_namespace)
154
+ raws = raw_fields(constraint)
108
155
  selector_xpaths(constraint, target_namespace).flat_map do |selector|
109
156
  Array(xml_element.moxml_element.xpath(selector)).map do |node|
110
- values = []
111
- ambiguous = false
112
- fields.each do |field|
113
- matched = field_nodes(node, field)
114
- # A field evaluating to a node-set with more than one
115
- # member violates the constraint (XSD 1.0 §3.11.4).
116
- ambiguous = true if matched.size > 1
117
- values << if matched.first
118
- field_node_value(matched.first)
119
- else
120
- field_supply_value(node, field, repository)
121
- end
122
- end
157
+ values, ambiguous, non_simple =
158
+ evaluate_field_row(node, fields, raws, constraint,
159
+ owner_element, repository)
123
160
 
124
161
  if ambiguous
125
162
  report_error(
@@ -133,6 +170,19 @@ module Lutaml
133
170
  next
134
171
  end
135
172
 
173
+ if non_simple
174
+ report_error(
175
+ collector,
176
+ code: "field_non_simple_type_violation",
177
+ message: "Field #{fields.join(', ')} of #{kind} " \
178
+ "'#{constraint.name}' evaluates to a node of " \
179
+ "non-simple type in '#{node.name}'",
180
+ location: xml_element.xpath,
181
+ context: { constraint: constraint.name },
182
+ )
183
+ next
184
+ end
185
+
136
186
  # A qualified node has every field present; an absent
137
187
  # field means the node does not contribute a row —
138
188
  # except for xs:KEY, where a selected node whose fields
@@ -287,6 +337,67 @@ module Lutaml
287
337
  repository.declared_attribute_supply(parent_type, attr_local)
288
338
  end
289
339
 
340
+ # Whether an element field's node supplies no identity value:
341
+ # it has element children, is declared non-simple (complex
342
+ # content or xsd:anyType — the typeless default), or carries a
343
+ # resolvable xsi:type override to a non-simple type — the
344
+ # override governs the INSTANCE value space, so a simple
345
+ # override keeps the field simple no matter what the schema
346
+ # declares (idF-class).
347
+ #
348
+ # @param matched [Moxml::Element]
349
+ # @return [Boolean]
350
+ def field_node_non_simple?(matched, constraint, raw_field,
351
+ owner_element, repository)
352
+ override = override_governs_simple(matched, repository)
353
+ return !override unless override.nil?
354
+
355
+ matched.elements.any? ||
356
+ declared_field_non_simple?(constraint, raw_field,
357
+ owner_element, repository)
358
+ end
359
+
360
+ # The simple/non-simple verdict of the field node's xsi:type
361
+ # override, or nil when the node has no resolvable override.
362
+ #
363
+ # @return [Boolean, nil]
364
+ def override_governs_simple(node, repository)
365
+ override = node.attributes.find do |candidate|
366
+ candidate.name == "type" &&
367
+ candidate.namespace&.uri == XSI_NAMESPACE
368
+ end
369
+ return unless override
370
+
371
+ parts = override.value.to_s.split(":")
372
+ local = parts.last
373
+ return if local.nil? || local.empty?
374
+ return local != "anyType" if %w[xs xsd].include?(parts.first)
375
+
376
+ case repository&.resolve_named_type(local)
377
+ when Lutaml::Xml::Schema::Xsd::SimpleType then true
378
+ when Lutaml::Xml::Schema::Xsd::ComplexType then false
379
+ end
380
+ end
381
+
382
+ # Whether the field's element declaration — reached by
383
+ # descending the IC owner's content model through the raw
384
+ # selector path, then the raw field step — is non-simple
385
+ # (complex content or xsd:anyType). Unresolvable paths allow
386
+ # no determination.
387
+ #
388
+ # @return [Boolean]
389
+ def declared_field_non_simple?(constraint, raw_field,
390
+ owner_element, repository)
391
+ return false unless repository && owner_element
392
+
393
+ owner_type = owner_element.complex_type ||
394
+ repository.resolve_type(owner_element)
395
+ raw_selectors(constraint).any? do |selector_raw|
396
+ repository.field_declaration_simple(owner_type, selector_raw,
397
+ raw_field) == false
398
+ end
399
+ end
400
+
290
401
  def report_duplicates(collector, xml_element, constraint, values,
291
402
  code)
292
403
  values.group_by(&:itself).each do |value, group|
@@ -342,6 +453,20 @@ module Lutaml
342
453
  end
343
454
  end
344
455
 
456
+ # The selector steps as WRITTEN (unions split the same way the
457
+ # adapted list splits) — the declared-field determination
458
+ # descends the schema through these.
459
+ #
460
+ # @return [Array<String>]
461
+ def raw_selectors(constraint)
462
+ raw = if constraint.selector.is_a?(Lutaml::Xml::Schema::Xsd::Selector)
463
+ constraint.selector.xpath
464
+ else
465
+ constraint.selector
466
+ end
467
+ raw.to_s.split(/\s*\|\s*/).reject(&:empty?)
468
+ end
469
+
345
470
  # The field steps as WRITTEN (unions split the same way the
346
471
  # adapted list splits) — the absent-row decision reads the
347
472
  # step's own namespace governance from these.
@@ -527,8 +527,228 @@ module Lutaml
527
527
  particle_for_type(resolve_named_type(local_name))
528
528
  end
529
529
 
530
+ # Whether the element declaration an identity-constraint field
531
+ # binds to is SIMPLE-typed. A field may take an identity value
532
+ # only from a simple-typed node: a complex type with complex
533
+ # content (element children, idK012) or xsd:anyType — the
534
+ # default for a typeless local declaration (idZ010's A3/A22) —
535
+ # supplies no identity value. The declaration is reached by
536
+ # descending the IC owner's content model through the raw
537
+ # selector path, then the selector element's own type through
538
+ # the raw field path.
539
+ #
540
+ # @param owner_type [Lutaml::Xml::Schema::Xsd::ComplexType, nil]
541
+ # @param selector_raw [String] the selector XPath as written
542
+ # @param field_raw [String] the field XPath as written
543
+ # @return [Boolean, nil] nil when unresolvable (no determination)
544
+ def field_declaration_simple(owner_type, selector_raw, field_raw)
545
+ sel_type = path_bound_type(owner_type, selector_raw)
546
+ bound = sel_type && path_bound_with_decl(sel_type, field_raw)
547
+ return unless bound
548
+
549
+ field_type, field_decl, owner_self = bound
550
+ return type_supplies_identity_value?(field_type) if owner_self
551
+ return unless field_decl
552
+
553
+ element_declaration_simple?(field_decl)
554
+ end
555
+
530
556
  private
531
557
 
558
+ # Whether a TYPE carries an identity value for a field bound to
559
+ # the selector node itself (a "." field): a simple type or a
560
+ # complex type with simple content does; complex content does not.
561
+ #
562
+ # @param type [Object]
563
+ # @return [Boolean, nil]
564
+ def type_supplies_identity_value?(type)
565
+ case type
566
+ when Lutaml::Xml::Schema::Xsd::SimpleType then true
567
+ when Lutaml::Xml::Schema::Xsd::ComplexType
568
+ !type.simple_content.nil?
569
+ end
570
+ end
571
+
572
+ # The type an identity-constraint XPath (selector or field)
573
+ # binds to, descended through the content model from +type+.
574
+ # A bare "." binds +type+ itself; each named step locates the
575
+ # child element declaration and descends into its type.
576
+ #
577
+ # @param type [Object, nil]
578
+ # @param raw_path [String] the XPath as written
579
+ # @return [Object, nil]
580
+ def path_bound_type(type, raw_path, depth = 0)
581
+ path_bound_with_decl(type, raw_path, depth)&.first
582
+ end
583
+
584
+ # The bound type AND the final element declaration of an
585
+ # identity-constraint XPath. The declaration is nil when the
586
+ # path is a bare "." (the bound node IS the starting element).
587
+ #
588
+ # @param type [Object, nil]
589
+ # @param raw_path [String] the XPath as written
590
+ # @return [Array(Object, Object, Boolean), nil] [type, decl,
591
+ # owner_self] — nil when unresolvable
592
+ def path_bound_with_decl(type, raw_path, depth = 0)
593
+ return nil if type.nil? || depth > 8
594
+
595
+ steps = raw_path.to_s.split("/").reject do |step|
596
+ step.empty? || step == "."
597
+ end
598
+ current = type
599
+ decl = nil
600
+ steps.each_with_index do |step, index|
601
+ local = step.split(":").last
602
+ return nil if step.start_with?("@") || local.nil? || local == "*"
603
+
604
+ decl = declared_child_element(current, local, depth)
605
+ return nil unless decl
606
+
607
+ current = declared_element_type(decl, depth)
608
+ # A nil type mid-path (typeless or unresolvable named)
609
+ # cannot descend further; a nil type on the FINAL step
610
+ # still binds its declaration — typeless defaults to
611
+ # xsd:anyType, which the caller's predicate decides.
612
+ return nil if current.nil? && index < steps.length - 1
613
+ end
614
+ [current, decl, steps.empty?]
615
+ end
616
+
617
+ # The element declaration for +local_name+ in the content model
618
+ # of +type+: its own particles first, then the derivation base
619
+ # chain (derived types inherit the base's particles).
620
+ #
621
+ # @param type [Object, nil]
622
+ # @param local_name [String]
623
+ # @param depth [Integer] recursion guard
624
+ # @return [Lutaml::Xml::Schema::Xsd::Element, nil]
625
+ def declared_child_element(type, local_name, depth = 0)
626
+ return nil if depth > 8
627
+ return nil unless type.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
628
+
629
+ found = find_particle_element(particle_for_type(type), local_name,
630
+ depth)
631
+ return found if found
632
+
633
+ content = type.complex_content
634
+ part = content && (Array(content.extension).first ||
635
+ Array(content.restriction).first)
636
+ return nil unless part
637
+
638
+ declared_child_element(
639
+ resolve_named_type(part.base.to_s.split(":").last),
640
+ local_name, depth + 1
641
+ )
642
+ end
643
+
644
+ # Depth-first search for an Element particle named +local_name+.
645
+ # A ref particle binds the GLOBAL declaration (the descent needs
646
+ # its type); prefix-insensitive, the same trade the adapted
647
+ # XPath evaluation makes.
648
+ #
649
+ # @param node [Object, Array, nil]
650
+ # @param local_name [String]
651
+ # @param depth [Integer] recursion guard
652
+ # @return [Lutaml::Xml::Schema::Xsd::Element, nil]
653
+ def find_particle_element(node, local_name, depth = 0)
654
+ return nil if node.nil? || depth > 24
655
+
656
+ if node.is_a?(Array)
657
+ node.each do |child|
658
+ found = find_particle_element(child, local_name, depth + 1)
659
+ return found if found
660
+ end
661
+ return nil
662
+ end
663
+
664
+ if node.is_a?(Lutaml::Xml::Schema::Xsd::Element)
665
+ return node if node.name.to_s.split(":").last == local_name
666
+
667
+ ref_local = node.ref.to_s.split(":").last
668
+ return nil unless ref_local == local_name
669
+
670
+ return resolve_global(ref_local, nil)
671
+ end
672
+
673
+ nested = CONTAINER_NESTED_KINDS[node.class]
674
+ nested&.each do |kind|
675
+ found = find_particle_element(Array(node.public_send(kind)),
676
+ local_name, depth + 1)
677
+ return found if found
678
+ end
679
+ (CONTAINER_LEAF_KINDS[node.class] || []).each do |kind|
680
+ Array(node.public_send(kind)).each do |leaf|
681
+ next unless leaf
682
+
683
+ if leaf.is_a?(Lutaml::Xml::Schema::Xsd::Group)
684
+ resolved = if leaf.ref
685
+ resolve_group(leaf.ref.to_s
686
+ .split(":").last)
687
+ else
688
+ leaf
689
+ end
690
+ found = find_particle_element(resolved, local_name,
691
+ depth + 1)
692
+ return found if found
693
+ elsif leaf.is_a?(Lutaml::Xml::Schema::Xsd::Element)
694
+ found = find_particle_element(leaf, local_name, depth + 1)
695
+ return found if found
696
+ end
697
+ end
698
+ end
699
+ nil
700
+ end
701
+
702
+ # The TYPE a bound element declaration carries: its inline
703
+ # complexType or simpleType, else the named type its +type+
704
+ # attribute resolves to.
705
+ #
706
+ # @param element_decl [Lutaml::Xml::Schema::Xsd::Element]
707
+ # @param depth [Integer] recursion guard
708
+ # @return [Object, nil]
709
+ def declared_element_type(element_decl, _depth = 0)
710
+ return element_decl.complex_type if element_decl.complex_type
711
+ return element_decl.simple_type if element_decl.simple_type
712
+
713
+ name = element_decl.type.to_s
714
+ return nil if name.empty?
715
+
716
+ resolve_named_type(name.split(":").last)
717
+ end
718
+
719
+ # Whether a bound element declaration's type is SIMPLE: an
720
+ # inline simpleType, a simple-named type, or a complex type
721
+ # with SIMPLE content (text value carries the identity value).
722
+ # Complex content — including xsd:anyType, the default for a
723
+ # typeless declaration — is NOT simple.
724
+ #
725
+ # @param element_decl [Lutaml::Xml::Schema::Xsd::Element]
726
+ # @return [Boolean, nil] nil when the named type is unresolvable
727
+ def element_declaration_simple?(element_decl)
728
+ return true if element_decl.simple_type
729
+
730
+ complex = element_decl.complex_type
731
+ return !complex.simple_content.nil? if complex
732
+
733
+ name = element_decl.type.to_s
734
+ return false if name.empty?
735
+
736
+ parts = name.split(":")
737
+ return false if parts.last == "anyType"
738
+
739
+ resolved = resolve_named_type(parts.last)
740
+ case resolved
741
+ when Lutaml::Xml::Schema::Xsd::SimpleType then true
742
+ when Lutaml::Xml::Schema::Xsd::ComplexType
743
+ !resolved.simple_content.nil?
744
+ else
745
+ # Unresolvable but builtin-prefixed (xs:/xsd: both bind the
746
+ # schema namespace) is simple; unresolvable otherwise allows
747
+ # no determination.
748
+ parts.first.to_s.match?(/\Axs(d)?\z/) || nil
749
+ end
750
+ end
751
+
532
752
  def particle_for_type(type)
533
753
  case type
534
754
  when Lutaml::Xml::Schema::Xsd::ComplexType
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.93"
5
+ VERSION = "1.2.95"
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.93
4
+ version: 1.2.95
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