lutaml-xsd 1.2.97 → 1.2.99

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: 74cc0c3c59a0cb1a80968d340ccf4d8be8b7d9ce9d1257c7e59044ebd85bc5b0
4
- data.tar.gz: 453526a2baaeb84186acb8f3d84b573ddaeb988af120acf601bd2e621cd159e2
3
+ metadata.gz: fa20de2fba923a0b6485653e7902c20694898ac8583b90f5e144b11b7ae61fc4
4
+ data.tar.gz: ccd4a57412cd1095538a9a72988d9b792f8f3ae213d4c644a401391d32cafcbc
5
5
  SHA512:
6
- metadata.gz: 67c01245e71827ab4682e6dda886b296586d96960b5e814b1b1e9ccbdee53d4fc33ee95ed705b90730e636f0f2c0ea5a7f325809072a7e0a0bd79d0928b91a79
7
- data.tar.gz: 3246ef0bfd177d2019fa3fd08b01409647d2d2d71c4bb8757e108a55c9374f72684f258e46419bece176a03f94a24a3c44c11ec484b38f9fe60e4114099f022e
6
+ metadata.gz: 421748a4d525018acc64f0a85f0d84b07320f456017bd06c481bb2cb0b97eeb8b394fbbed64a50f8c3e037277a627d8aa322aabbb2eb9983861f798c78126734
7
+ data.tar.gz: 63b4a57e42b8431ab7cec97f0fd015520c991c1ff8ab4017a7f4210f1d9b3f7f3480c8fca5e4c7ddc11079e818bfe4211030ef30cdeb4e6e04714468ca1015d7
data/TODO.conformance.md CHANGED
@@ -523,7 +523,41 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
523
523
  \p{Is...} per-block tests) plus the reL/reP/reQ/reR/reS/reT
524
524
  series — filed leptris-rs#47; moxml 0.6.3 regressed 5 attribute
525
525
  cases (addB059/196c/197c, attO009/011) — filed moxml#529. THE
526
+ - REDEFINE-GROUP ROUND (2026-11-07): +2 ModelGroups (mgO006,
527
+ mgO034; suite 4622->4624 = 98.46%, zero regressions, rspec
528
+ green). index_redefine registered simpleType bodies
529
+ (@redefined_simple_bodies) and attributeGroup bodies
530
+ (@attribute_groups) but NOT group bodies — resolve_group walked
531
+ the schemas and found the TARGET original (mgO006B's
532
+ all(e1, e2?)) instead of the redefining body (choice(e1)), so
533
+ foo's sequence(e1, group-ref) saw two e1s against the all's
534
+ max-1 and false-positived occurrence bounds. The body IS the
535
+ effective definition for every reference to the name (§4.2.2 —
536
+ the same principle the simple-type round landed for stZ033).
537
+ Group sentinels (schT redefine trio, groupG/H/J, idF/G engine
538
+ legs) unchanged.
539
+
526
540
  STACK IS PINNED BACK to the known-good 1.9.406.0/0.6.2/0.8.161
541
+ - SKIP-WILDCARD-FIELD ROUND (2026-11-07): +1 IC (idZ015; suite
542
+ 4621->4622 = 98.42%, zero regressions, rspec green). THE LAST IC
543
+ SINGLETON — the idK/idZ family is now CLEAN (all six roots fixed
544
+ across the four rounds). An attribute admitted by a
545
+ processContents=skip wildcard is NOT ASSESSED, so it supplies no
546
+ identity-constraint field value: the field treats it as absent and
547
+ a key whose fields do not all evaluate is violated (idZ015: foo's
548
+ ##any skip anyAttribute + key field @bar; xmllint: "Not all fields
549
+ of key identity-constraint evaluate to a node"). The skip check
550
+ walks the selector node's declaration anyAttribute wildcards
551
+ (own + content parts + attributeGroup members, depth 3) and the
552
+ namespace constraint reads the attribute's URI from the MOXML
553
+ element wrapper — xpath result attributes are ADAPTER objects
554
+ (leptris ResultAttr carries no namespace). GOTCHA: the first
555
+ implementation read node.namespace and CRASHED under leptris —
556
+ the suite probe "passed" as CRASH-AS-INVALID, caught by writing
557
+ the rule-level spec FIRST (rule_execution_error instead of the
558
+ finding). Suite verdicts from crashes are not fixes; assert the
559
+ finding code.
560
+
527
561
  (98.28% restored, zero regressions vs the 406 baseline). The
528
562
  - IDREF-RESOLUTION ROUND (2026-11-07): +1 IC (idZ012; suite
529
563
  4620->4621 = 98.40%, zero regressions, rspec green). Every
@@ -128,6 +128,14 @@ module Lutaml
128
128
  ambiguous = true if matched.size > 1
129
129
  values << if matched.first.nil?
130
130
  field_supply_value(node, field, repository)
131
+ elsif !matched.first.is_a?(Moxml::Element) &&
132
+ skip_governed_attribute?(node, matched.first,
133
+ repository)
134
+ # A skip-wildcard-governed attribute is not
135
+ # assessed, so it supplies no identity-
136
+ # constraint value: the field treats it as
137
+ # absent (idZ015).
138
+ nil
131
139
  elsif matched.first.is_a?(Moxml::Element) &&
132
140
  field_node_non_simple?(
133
141
  matched.first, constraint, raws[index],
@@ -337,6 +345,104 @@ module Lutaml
337
345
  repository.declared_attribute_supply(parent_type, attr_local)
338
346
  end
339
347
 
348
+ # Whether the instance attribute is governed by a SKIP
349
+ # wildcard on the selector node's declaration: a skip-
350
+ # governed attribute is not assessed, so it supplies no
351
+ # identity-constraint field value (idZ015).
352
+ #
353
+ # @return [Boolean]
354
+ def skip_governed_attribute?(element_node, attribute_node,
355
+ repository)
356
+ declaration = repository&.resolve(element_node.name,
357
+ element_node.namespace_uri)
358
+ return false unless declaration
359
+
360
+ type = declaration.complex_type ||
361
+ repository.resolve_type(declaration)
362
+ return false unless type.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
363
+
364
+ target_ns = repository.target_namespace_for(declaration)
365
+ attribute_ns = attribute_namespace(element_node, attribute_node)
366
+ attribute_skip_wildcards(type, repository, 0).any? do |wildcard|
367
+ wildcard_process_mode(wildcard) == "skip" &&
368
+ wildcard_admits_namespace?(wildcard, attribute_ns, target_ns)
369
+ end
370
+ end
371
+
372
+ # The attribute's namespace URI: the xpath result nodes are
373
+ # adapter objects (leptris ResultAttr carries no namespace),
374
+ # so the name-matched attribute on the MOXML element wrapper
375
+ # resolves it.
376
+ #
377
+ # @return [String]
378
+ def attribute_namespace(element_node, attribute_node)
379
+ found = element_node.attributes.find do |candidate|
380
+ candidate.name == attribute_node.name
381
+ end
382
+ found&.namespace&.uri.to_s
383
+ end
384
+
385
+ # The anyAttribute wildcards reachable from the type: its own,
386
+ # content-part bodies, and attributeGroup members (nested
387
+ # refs depth-guarded).
388
+ #
389
+ # @return [Array<Lutaml::Xml::Schema::Xsd::AnyAttribute>]
390
+ def attribute_skip_wildcards(type, repository, depth)
391
+ return [] if depth > 3
392
+
393
+ wildcards = Array(type.any_attribute)
394
+ Array(type.attribute_group).each do |group|
395
+ wildcards.concat(Array(group.any_attribute))
396
+ local = (group.ref || group.name).to_s.split(":").last
397
+ declaration = local && repository.resolve_attribute_group(local)
398
+ if declaration
399
+ wildcards.concat(attribute_skip_wildcards(declaration,
400
+ repository,
401
+ depth + 1))
402
+ end
403
+ end
404
+ content_kinds = %i[complex_content simple_content]
405
+ part_kinds = %i[extension restriction]
406
+ content_kinds.each do |content_kind|
407
+ content = type.public_send(content_kind)
408
+ next unless content
409
+
410
+ part_kinds.each do |part_kind|
411
+ Array(content.public_send(part_kind)).each do |part|
412
+ wildcards.concat(Array(part.any_attribute))
413
+ end
414
+ end
415
+ end
416
+ wildcards
417
+ end
418
+
419
+ # Whether the wildcard's namespace constraint admits the
420
+ # attribute's namespace (mirrors WildcardScope#wildcard_permits?
421
+ # for attribute nodes, against the declaration's target
422
+ # namespace).
423
+ #
424
+ # @return [Boolean]
425
+ def wildcard_admits_namespace?(wildcard, uri, target_ns)
426
+ case wildcard.namespace.to_s
427
+ when "##any", ""
428
+ true
429
+ when "##other"
430
+ !uri.empty? && uri != target_ns.to_s
431
+ when "##local"
432
+ uri.empty?
433
+ when "##targetNamespace"
434
+ uri == target_ns.to_s
435
+ else
436
+ wildcard.namespace.to_s.split(/\s+/).any? do |entry|
437
+ case entry
438
+ when "##local" then uri.empty?
439
+ when "##targetNamespace" then uri == target_ns.to_s
440
+ else entry == uri
441
+ end
442
+ end
443
+ end
444
+ end
445
+
340
446
  # Whether an element field's node supplies no identity value:
341
447
  # it has element children, is declared non-simple (complex
342
448
  # content or xsd:anyType — the typeless default), or carries a
@@ -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
+ # Redefine GROUP bodies: the body is the effective definition
69
+ # for every reference to the name (§4.2.2 — same principle as
70
+ # the simple-type bodies; mgO006/034: the body's choice(e1)
71
+ # replaces the target's all(...)).
72
+ @redefined_groups = {}
68
73
  # Exact namespaces for PREFIXED ref particles, from the
69
74
  # owning schema's xmlns declarations (lutaml-model 0.8.167
70
75
  # retains them — #1131). The prefix IS the semantics: a ref
@@ -483,6 +488,11 @@ module Lutaml
483
488
  def resolve_group(local_name)
484
489
  return nil if local_name.nil? || local_name.empty?
485
490
 
491
+ # A redefine body is the effective definition for every
492
+ # reference to the name — the target originals never serve.
493
+ body = @redefined_groups[local_name]
494
+ return body if body
495
+
486
496
  schemas.each do |schema|
487
497
  found = Array(schema.group).find { |g| g.name == local_name }
488
498
  return found if found
@@ -1040,6 +1050,12 @@ module Lutaml
1040
1050
  @redefined_originals[name] = original if original
1041
1051
  @attribute_groups[name] = group
1042
1052
  end
1053
+ Array(red.group).each do |group|
1054
+ name = group.name.to_s
1055
+ next if name.empty?
1056
+
1057
+ @redefined_groups[name] = group
1058
+ end
1043
1059
  end
1044
1060
 
1045
1061
  def index_attribute(attribute, namespace)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.97"
5
+ VERSION = "1.2.99"
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.97
4
+ version: 1.2.99
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.