lutaml-xsd 1.2.77 → 1.2.78

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: 9348b8456689993378705b9289ce593db195f7440d77aeb6aaf5d5dda095cc68
4
- data.tar.gz: 958720fe60cf140d78ebe3891069d4e0f64ffa37f37290c24f236499ae8dc187
3
+ metadata.gz: 22d795e689f88ccef5f61459e717e04bafc7eaf5504b080a6062a59d9501a86e
4
+ data.tar.gz: fb39b92dc122c263bf6b144c70d7f6eaee7841209f8d2ad8a013daa540c13f5c
5
5
  SHA512:
6
- metadata.gz: 9e883e13a5538b8d26493881aef3512513a12952fcc08f464f16ce77e2cde3142bfe082b85700a9b6545a6e2e4bf546d7449408a9d3e20af5175541622ab202b
7
- data.tar.gz: 31990577df015678c7986199fda9ab5e751be44925b5bcf6a7eaa198e32eb884f6ad98920873070ed4f70d2b1f1a0d41084769911bc1f0f9c9e2450ce05e3e89
6
+ metadata.gz: 311267aaa35718e4f3c149ed3d7e7f14eda7bee3a077ca39c6c5c4041ca70184bd4aa458c2680ed435295bbe8460bf0b1b96ce77d473225062e5afa6439cc353
7
+ data.tar.gz: 36edcae8faa4d6062edc3f873cc34e0c67c01c156089c1517ed21cb265df5e66729ca5588264eb856476705f62e59879c3bf47aed112497b97f5b16c17475d23
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lutaml-xsd (1.2.77)
4
+ lutaml-xsd (1.2.78)
5
5
  liquid (>= 4.0, < 6.0)
6
6
  lutaml-model (~> 0.8.123)
7
7
  lutaml-store (~> 0.3)
@@ -264,7 +264,7 @@ CHECKSUMS
264
264
  liquid (5.14.0) sha256=e1020c2b2ee58c7a4d3bfdc7a331537bd27a783353748bff0bf27c6ac0c17065
265
265
  lutaml-model (0.8.155) sha256=3d90f2fb4fdf41a42d4a05b62b3f6644b433070b82291a9371deaa8e68a1e02d
266
266
  lutaml-store (0.3.2) sha256=9c455dbab32b4c635c48a27213f6f56fda191731c4574eb6187184ba0588a672
267
- lutaml-xsd (1.2.77)
267
+ lutaml-xsd (1.2.78)
268
268
  memo_wise (1.13.0) sha256=30220c38c4cef410849bc73553c58664dc2c91c6379e4a1df22aea02358b716b
269
269
  moxml (0.6.1) sha256=5b7677258bbad372f0725a421f8adeae37b65d6f7871da2747e2c1906cdac7ea
270
270
  nokogiri (1.19.4-aarch64-linux-gnu) sha256=1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f
data/TODO.conformance.md CHANGED
@@ -120,21 +120,21 @@ pinned commit) is measured via `rake conformance:w3c`:
120
120
 
121
121
  | mode | pass-rate |
122
122
  |---|---|
123
- | pipeline | 4557/4696 (97.0%) |
123
+ | pipeline | 4565/4696 (97.2%) |
124
124
 
125
125
  (2026-11-02, bundled-stack measurement on main with the escape,
126
126
  hint-following, pattern-alternative, identity-crash, engine-set,
127
127
  engine-refresh, IC value-space, IC field-resolution, facade-silence,
128
128
  regex-semantics, redefine-refresh, gmonth-refresh, digit-vintage,
129
- stgh-refresh and group-ref rounds; moxml 0.6.1 (gemspec floor
130
- `~> 0.6.0` per the owner — the 0.6 line drops the Opal surface;
131
- measured conformance-neutral), lutaml-model 0.8.155, engine leptris
132
- 1.9.401.0.) Same-stack comparison: 1.2.43 baseline 3961 (84.3%) →
133
- 4039 (86.0%) → 4090 (87.1%) → 4360 (92.8%, lockfile refresh) → 4411
134
- (93.9%) → 4430 (94.3%) → 4435 (94.4%) → 4436 (94.5%) → 4439 (94.5%)
135
- → 4454 (94.9%) → 4495 (95.7%) → 4524 (96.3%) → 4534 (96.6%) → 4540
136
- (96.7%) → 4542 (96.7%) → 4546 (96.8%) → 4557 (97.0%), +596 net over
137
- the 1.2.43 baseline. The escapes round (PR #197 — \d→\p{Nd},
129
+ stgh-refresh, group-ref and attribute-group-redefine rounds; moxml
130
+ 0.6.1 (gemspec floor `~> 0.6.0` per the owner — the 0.6 line drops
131
+ the Opal surface; measured conformance-neutral), lutaml-model
132
+ 0.8.155, engine leptris 1.9.401.0.) Same-stack comparison: 1.2.43
133
+ baseline 3961 (84.3%) → 4039 (86.0%) → 4090 (87.1%) → 4360 (92.8%,
134
+ lockfile refresh) → 4411 (93.9%) → 4430 (94.3%) → 4435 (94.4%) →
135
+ 4436 (94.5%) → 4439 (94.5%) → 4454 (94.9%) → 4495 (95.7%) → 4524
136
+ (96.3%) → 4534 (96.6%) → 4540 (96.7%) → 4542 (96.7%) → 4546 (96.8%)
137
+ → 4557 (97.0%) → 4565 (97.2%), +604 net over the 1.2.43 baseline. The escapes round (PR #197 — \d→\p{Nd},
138
138
  \w/\W/\s to their XSD value spaces) collapses Regex 120→69;
139
139
  same-step pattern facets now behave as alternatives and
140
140
  whitespace-only text reaches the facets intact (PR #200), Regex
@@ -358,6 +358,20 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
358
358
  zero regressions. Group remainder: groupB009/010 + groupO004
359
359
  (false-reject class), groupH008/J003/006/008/L008 under-detections
360
360
  (choice-of-group capacity depth).
361
+ - ATTRIBUTE-GROUP-REDEFINE ROUND (2026-11-02, PR #218): +8 net
362
+ (AttributeGroup 17→11, Schema 14→12, Attribute 10→9; suite
363
+ 4557→4565 = 97.2%). lutaml-model does NOT chase xs:redefine
364
+ targets — the original document was never parsed, so the
365
+ redefined group's self-ref hook had nothing to hook to and
366
+ expansions truncated at the cycle guard. The resolver now chases
367
+ the redefine target itself (relative to the defining file, via
368
+ the repository's source path), indexes it, keeps the ORIGINAL
369
+ declaration as the hook target, and expands the redefining body
370
+ with the self-ref resolved to that original (attgC007/attgD036).
371
+ Wildcards nested in attributeGroup DECLARATIONS reach types
372
+ through the group's resolution (attgD019). All remaining
373
+ AttributeGroup failures are ENGINE-only strict re-checks on
374
+ composed shapes (the moxml#510 thread).
361
375
  - REGEX SEMANTICS ROUND (2026-10-31, PR #208): \w/\W now carry their
362
376
  Appendix F complements (\w = [^\p{P}\p{Z}\p{C}], class interiors
363
377
  via the exact positive partition L/M/N/S), \I/\C complements added
@@ -268,14 +268,23 @@ module Lutaml
268
268
  return [] if depth > 5
269
269
  return [] unless group
270
270
 
271
+ own = (group.name || group.ref).to_s.split(":").last
271
272
  attrs = Array(group.attribute)
272
273
 
273
274
  # An attributeGroup may reference other attributeGroups —
274
- # their declarations flow into the expansion (attgD004).
275
+ # their declarations flow into the expansion (attgD004). A
276
+ # reference to the group's OWN name inside an xs:redefine
277
+ # body is the §4.2.2 hook to the ORIGINAL definition.
275
278
  Array(group.attribute_group).each do |nested_ref|
276
279
  local = (nested_ref.ref || nested_ref.name).to_s
277
280
  .split(":").last
278
- declaration = repository&.resolve_attribute_group(local)
281
+ declaration =
282
+ if !local.empty? && local == own &&
283
+ repository&.redefined_original_for(local)
284
+ repository.redefined_original_for(local)
285
+ else
286
+ repository&.resolve_attribute_group(local)
287
+ end
279
288
  next unless declaration
280
289
 
281
290
  attrs.concat(expand_attribute_group(declaration, repository,
@@ -889,10 +898,15 @@ module Lutaml
889
898
  complex_type_wildcard_support?
890
899
  wildcards << complex_wildcard if complex_wildcard
891
900
 
901
+ # A wildcard nested in an attributeGroup DECLARATION reaches
902
+ # the type only through the group's resolution — the type's
903
+ # ref particle carries no children of its own (attgD019).
892
904
  Array(schema_def.attribute_group).each do |group|
893
905
  Array(group.any_attribute).each do |wildcard|
894
906
  wildcards << wildcard
895
907
  end
908
+
909
+ collect_group_wildcards(group, repository, wildcards, 0)
896
910
  end
897
911
 
898
912
  CONTENT_KINDS.each do |content_kind|
@@ -916,6 +930,29 @@ module Lutaml
916
930
  wildcards
917
931
  end
918
932
 
933
+ # The wildcards of an attributeGroup reference's DECLARATION,
934
+ # following nested attributeGroup refs (depth-guarded).
935
+ #
936
+ # @return [void]
937
+ def collect_group_wildcards(group, repository, wildcards, depth)
938
+ return if depth > 5
939
+
940
+ local = (group.ref || group.name).to_s.split(":").last
941
+ return if local.to_s.empty?
942
+
943
+ declaration = repository&.resolve_attribute_group(local)
944
+ return unless declaration
945
+
946
+ Array(declaration.any_attribute).each do |wildcard|
947
+ wildcards << wildcard
948
+ end
949
+
950
+ Array(declaration.attribute_group).each do |nested|
951
+ collect_group_wildcards(nested, repository, wildcards,
952
+ depth + 1)
953
+ end
954
+ end
955
+
919
956
  # The named base type of the derivation shape, when present.
920
957
  #
921
958
  # @return [Lutaml::Xml::Schema::Xsd::ComplexType, nil]
@@ -49,6 +49,7 @@ module Lutaml
49
49
  @named_types = {}
50
50
  @attributes = Hash.new { |hash, key| hash[key] = [] }
51
51
  @attribute_groups = {}
52
+ @redefined_originals = {}
52
53
  @elements = index_elements
53
54
  end
54
55
 
@@ -100,6 +101,16 @@ module Lutaml
100
101
  @attribute_groups[local_name]
101
102
  end
102
103
 
104
+ # The pre-redefinition declaration of an attributeGroup that an
105
+ # xs:redefine replaced — the target of the redefining body's
106
+ # self-reference hook.
107
+ #
108
+ # @param local_name [String]
109
+ # @return [Object, nil]
110
+ def redefined_original_for(local_name)
111
+ @redefined_originals[local_name]
112
+ end
113
+
103
114
  # Owner schema's target namespace for a resolved declaration
104
115
  # (parsed element models carry no owner-schema link).
105
116
  #
@@ -538,6 +549,46 @@ module Lutaml
538
549
 
539
550
  index_schema(index, nested)
540
551
  end
552
+
553
+ # xs:redefine replaces an attributeGroup with a body whose
554
+ # self-reference is the §4.2.2 hook to the ORIGINAL
555
+ # definition. lutaml-model does NOT chase the redefine
556
+ # target, so the original document is parsed here (relative
557
+ # to the defining file) and indexed; the original
558
+ # declaration is kept for that hook and the redefining body
559
+ # indexed under the name (attgC007/attgD036). Runs after the
560
+ # nested descent so included declarations are already in.
561
+ Array(schema.redefine).each do |red|
562
+ target_path = nil
563
+ base = begin
564
+ File.dirname(@repository.source_path_for(schema))
565
+ rescue StandardError
566
+ nil
567
+ end
568
+ if base && red.schema_path.to_s.match?(/\S/)
569
+ candidate = File.expand_path(red.schema_path.to_s, base)
570
+ target_path = candidate if File.exist?(candidate)
571
+ end
572
+ if target_path
573
+ begin
574
+ target = Lutaml::Xml::Schema::Xsd.parse(
575
+ File.read(target_path), location: target_path
576
+ )
577
+ index_schema(index, target, held_signatures, namespace,
578
+ defaults_schema)
579
+ rescue StandardError
580
+ nil
581
+ end
582
+ end
583
+ Array(red.attribute_group).each do |group|
584
+ name = group.name.to_s
585
+ next if name.empty?
586
+
587
+ original = @attribute_groups[name]
588
+ @redefined_originals[name] = original if original
589
+ @attribute_groups[name] = group
590
+ end
591
+ end
541
592
  end
542
593
 
543
594
  def index_attribute(attribute, namespace)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.77"
5
+ VERSION = "1.2.78"
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.77
4
+ version: 1.2.78
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.