lutaml-xsd 1.2.83 → 1.2.84

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: efe4fbd2d864e7cbe9218faaf7f67fc879c4e20cc32c54e04761fcee59d2d1dc
4
- data.tar.gz: 3b5618daa924a8a493645bab5ea7f0408d3b9245c32695306131c1cb9a0cfeb8
3
+ metadata.gz: 0ba83c4ddd3e8f05926b71bd53ed35e0aba700381e1ca5ed13c803ac2164412b
4
+ data.tar.gz: ae5e50d04a1a0230afbbdf904484601800b5772b2348c2b374feef2fa75403d7
5
5
  SHA512:
6
- metadata.gz: 909c81244dd126cbbb8843fcd3a010f5da4a3c70bd325b71ed5865496cc390d101fecb6d6a4c38069b350abad064c4837328f5ee28cdcb583b4ec5e439c629da
7
- data.tar.gz: 34a60915d85511b36be444dc6903e8f3f221e6740d3d6147fd5966c0fe82a852896dffb20fbf6253376bb78abeaa4a2717da83b4b44e644739acda1e85105c33
6
+ metadata.gz: 6d52035a236b15bc9a063269dd5ee14389ec12d36619eb22cfcc85bbb9e98e17b2aedd55e41b6dbcbf7eb9e2f1797aaf83423b58d657e6e281befd52ab61c928
7
+ data.tar.gz: 6b35f257dbc8cadcd929212015294b407c2e5836c375e568a24bf71f05e41eb9823fbb97bf167f7bc289792e9a0f1d8f060088a7931594bc1b5d96aa99992a11
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 | 4585/4696 (97.64%) |
123
+ | pipeline | 4588/4696 (97.7%) |
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), +624 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), +627 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
@@ -494,6 +494,20 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
494
494
  lutaml-model Redefine model shape study). Remaining Schema 9:
495
495
  schA1/Q1/D10/F2 (ours), schD7/G8 (lutaml-model#1087),
496
496
  schF1/G2/G7/P2 (moxml#510 composed bindings).
497
+ - TYPE-BINDING ROUND (2026-11-03): +3 (Schema 9→8 — schQ1/schF2
498
+ flip; Particles 12→8 cumulatively with the collision round; suite
499
+ 4585→4588 = 97.7%, zero regressions, rspec green). Same-local-name
500
+ types across a composition (three documents each declaring ct-A in
501
+ ns-a/ns-b/no-namespace) resolved to the FIRST candidate; the
502
+ resolver now keeps every candidate in document order and prefers
503
+ the one declared in the OWNING declaration's namespace (type
504
+ namespaces indexed at index time), with the no-namespace owner
505
+ preferring the no-namespace candidate; xsi:type overrides and
506
+ extension-base walks thread the deriving type namespace through.
507
+ STILL OPEN: schA1/schD10 (the hinted composition's CHILD value
508
+ checks bind the no-ns int ct-A to the ns-b boolean children —
509
+ 'true' vs xsd:int — the per-child type plumbing under hint
510
+ layering), full type-redefine body semantics.
497
511
  - REGEX SEMANTICS ROUND (2026-10-31, PR #208): \w/\W now carry their
498
512
  Appendix F complements (\w = [^\p{P}\p{Z}\p{C}], class interiors
499
513
  via the exact positive partition L/M/N/S), \I/\C complements added
@@ -247,7 +247,9 @@ module Lutaml
247
247
  xsi = repository && xsi_attribute(xml_element, "type")
248
248
  if xsi&.value.to_s.match?(/\S/)
249
249
  local = xsi.value.to_s.split(":").last
250
- named = repository.resolve_named_type(local)
250
+ named = repository.resolve_named_type(
251
+ local, repository.target_namespace_for(schema_def)
252
+ )
251
253
  return nil unless named
252
254
 
253
255
  return type_particles(named, repository, {}.compare_by_identity)
@@ -303,7 +305,9 @@ module Lutaml
303
305
  if extension
304
306
  base_local = extension.base.to_s.split(":").last
305
307
  base_type = base_local &&
306
- repository&.resolve_named_type(base_local)
308
+ repository&.resolve_named_type(
309
+ base_local, repository&.target_namespace_for(type)
310
+ )
307
311
  particles = type_particles(base_type, repository, seen) +
308
312
  particles
309
313
  COMPLEX_PARTICLE_KINDS.each do |kind|
@@ -186,6 +186,9 @@ module Lutaml
186
186
  end
187
187
 
188
188
  # Named type for an element's `type="prefix:Name"` reference.
189
+ # Same-local-name types across composed documents resolve by
190
+ # the OWNING declaration's namespace (schA1: ct-A exists in
191
+ # ns-a/ns-b/no-namespace; the reference binds its own).
189
192
  #
190
193
  # @param schema_element [Lutaml::Xml::Schema::Xsd::Element, nil]
191
194
  # @return [Object, nil]
@@ -195,40 +198,67 @@ module Lutaml
195
198
  reference = schema_element.type
196
199
  return nil if reference.nil? || reference.to_s.empty?
197
200
 
198
- resolve_named_type(reference.to_s.split(":").last)
201
+ resolve_named_type(reference.to_s.split(":").last,
202
+ target_namespace_for(schema_element))
199
203
  end
200
204
 
201
- # Named complex or simple type by local name.
205
+ # Named complex or simple type by local name, preferring a
206
+ # candidate declared in owner_ns.
202
207
  #
203
208
  # @param local_name [String]
209
+ # @param owner_ns [String, nil] the referencing declaration's
210
+ # target namespace
204
211
  # @return [Object, nil]
205
- def resolve_named_type(local_name)
212
+ def resolve_named_type(local_name, owner_ns = nil)
206
213
  return nil if local_name.nil? || local_name.empty?
207
- return @named_types[local_name] if @named_types.key?(local_name)
208
214
 
209
- result = nil
210
- schemas.each do |schema|
211
- result = named_type_in(local_name, schema)
212
- break if result
215
+ list = named_type_candidates(local_name)
216
+ return nil if list.empty?
217
+ # A nil owner means the referencing declaration lives in NO
218
+ # namespace (schA1_c): prefer the no-namespace candidate, not
219
+ # just the first.
220
+ if owner_ns.nil?
221
+ return list.find { |t| @namespaces[t].to_s.empty? } ||
222
+ list.first
213
223
  end
214
- if result.nil? && !@redefined_body_names.include?(local_name)
215
- @redefined_targets.each do |schema|
216
- result = named_type_in(local_name, schema)
217
- break if result
218
- end
219
- end
220
- @named_types[local_name] = result
224
+
225
+ list.find { |t| @namespaces[t] == owner_ns } || list.first
221
226
  end
222
227
 
223
- # @return [Object, nil]
224
- def named_type_in(local_name, schema)
225
- found = Array(schema.complex_type).find do |ct|
226
- ct.name == local_name
228
+ # Every top-level and nested declaration of the name, in
229
+ # document order: schemas first, then parsed redefine targets
230
+ # (names a redefine body redefines stay off the targets).
231
+ #
232
+ # @return [Array<Object>]
233
+ def named_type_candidates(local_name)
234
+ cache = @named_type_lists ||= {}
235
+ return cache[local_name] if cache.key?(local_name)
236
+
237
+ list = []
238
+ schemas.each do |schema|
239
+ found = Array(schema.complex_type).find do |ct|
240
+ ct.name == local_name
241
+ end
242
+ found ||= Array(schema.simple_type).find do |st|
243
+ st.name == local_name
244
+ end
245
+ list << found if found
246
+
247
+ nested = find_nested_named_type(local_name, schema)
248
+ list << nested if nested
227
249
  end
228
- found ||= Array(schema.simple_type).find do |st|
229
- st.name == local_name
250
+ unless @redefined_body_names.include?(local_name)
251
+ @redefined_targets.each do |schema|
252
+ found = Array(schema.complex_type).find do |ct|
253
+ ct.name == local_name
254
+ end
255
+ found ||= Array(schema.simple_type).find do |st|
256
+ st.name == local_name
257
+ end
258
+ list << found if found
259
+ end
230
260
  end
231
- found || find_nested_named_type(local_name, schema)
261
+ cache[local_name] = list.uniq
232
262
  end
233
263
 
234
264
  # Named types declared in documents reached through resolved
@@ -767,6 +797,7 @@ module Lutaml
767
797
  def index_type(index, complex_type, namespace, schema)
768
798
  return unless complex_type
769
799
 
800
+ @namespaces[complex_type] = namespace
770
801
  each_particle_element(complex_type, schema) do |element|
771
802
  index_element(index, element, namespace, :inline, schema)
772
803
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.83"
5
+ VERSION = "1.2.84"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-xsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.83
4
+ version: 1.2.84
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.