lutaml-xsd 1.2.98 → 1.2.100

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: e129470c8c939e17b19e748ffaebf593f7f3909876fbe05e1b733e1129f448ba
4
- data.tar.gz: '03015085efe53c4dca6dec3bc5115d9081b42a24c2f758b19c4c3424b672521f'
3
+ metadata.gz: 2fb04a8aef728bbfb826bd9e49561e8a2e4949a0a8da01afb5d3f0306b50a14e
4
+ data.tar.gz: 438fdfc6d197d4f1aa146232aa5a2d73c77f2181b0925c2d44328631876dd433
5
5
  SHA512:
6
- metadata.gz: 4e1be4de4f925cb152fa5f69e2cb57fb42d9337ab37628b71314ab0e3bc7a5d10da9cf829173a78303c0e8e495682286bb9ecf4bde0d72056324d6e572d309cc
7
- data.tar.gz: ae47a5ca4b9bc803c7e7c35aaeb0a9e8a35e9610bddacdd82d14b269310863f91d64a9f59f1cd9f0014ea72dd0040f975098feccd30914fc6e7cf053845a9b91
6
+ metadata.gz: 2a7fb730886d8296d8c3daff45401f6b7b1dc817a5030ce1f9a5170914290cc95c6bc532eb6f42eecb9a85026686b0e5ecca47ca2f7d9b0f9b70ba68d5c71413
7
+ data.tar.gz: dbe58ef59e792eb32eb0b42f6db501a797cc8423fea41656d89e20ec7b79257e279832ad0ef4c2c5e1ede93f142b6e66fdd5fdf09599f5b55fafef6c11d588ce
data/TODO.conformance.md CHANGED
@@ -522,7 +522,39 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
522
522
  ~177 cases — the ENTIRE Unicode-block escape family (~80
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
+ - WILDCARD-LAYERING ROUND (2026-11-07): +3 Wildcards (wildZ013b/c
526
+ valid, wildZ013e invalid; suite 4624->4627 = 98.57%, zero
527
+ regressions, rspec green). THREE defects: (1) attributeGroup refs
528
+ nested in content parts never contributed their anyAttribute
529
+ wildcards (wildZ013b — the extension's attG2-51 ref); (2) the
530
+ derivation wildcard list admitted with plain UNION semantics where
531
+ same-type wildcards must INTERSECT (wildZ013e: intersection1's
532
+ ##other + ##local b c give set(b, c) — absent-ns attributes fail
533
+ ##other) — collect_any_attribute now returns one GROUP per
534
+ derivation layer: groups union (the extension union, ctH011
535
+ unchanged), members intersect; (3) the chameleon import's ##other
536
+ evaluated against the INCLUDER's target namespace — the
537
+ per-wildcard owner tns (indexed for attributeGroup declarations
538
+ and redefine bodies now) evaluates a chameleon's ##other against
539
+ its own ABSENT target (wildZ013c's ##local b c + ##other(not-
540
+ absent) admit everything the instance carries). Family: Wildcards
541
+ + Attribute clean; AttributeGroup 14 = the parked moxml#522 set.
542
+
525
543
  cases (addB059/196c/197c, attO009/011) — filed moxml#529. THE
544
+ - REDEFINE-GROUP ROUND (2026-11-07): +2 ModelGroups (mgO006,
545
+ mgO034; suite 4622->4624 = 98.46%, zero regressions, rspec
546
+ green). index_redefine registered simpleType bodies
547
+ (@redefined_simple_bodies) and attributeGroup bodies
548
+ (@attribute_groups) but NOT group bodies — resolve_group walked
549
+ the schemas and found the TARGET original (mgO006B's
550
+ all(e1, e2?)) instead of the redefining body (choice(e1)), so
551
+ foo's sequence(e1, group-ref) saw two e1s against the all's
552
+ max-1 and false-positived occurrence bounds. The body IS the
553
+ effective definition for every reference to the name (§4.2.2 —
554
+ the same principle the simple-type round landed for stZ033).
555
+ Group sentinels (schT redefine trio, groupG/H/J, idF/G engine
556
+ legs) unchanged.
557
+
526
558
  STACK IS PINNED BACK to the known-good 1.9.406.0/0.6.2/0.8.161
527
559
  - SKIP-WILDCARD-FIELD ROUND (2026-11-07): +1 IC (idZ015; suite
528
560
  4621->4622 = 98.42%, zero regressions, rspec green). THE LAST IC
@@ -538,9 +538,14 @@ module Lutaml
538
538
 
539
539
  xml_attr = xml_attrs.find { |xa| xa.name == attr_name }
540
540
  next unless xml_attr
541
- next if wildcards.any? do |wildcard|
542
- wildcard_permits_attribute?(wildcard, xml_element, xml_attr,
543
- nil)
541
+ # A wildcard that admits the attribute shadows the
542
+ # prohibition (attZ002): any group admitting (union
543
+ # across layers, intersection within).
544
+ next if wildcards.any? do |group|
545
+ group.all? do |wildcard|
546
+ wildcard_permits_attribute?(wildcard, xml_element,
547
+ xml_attr, nil)
548
+ end
544
549
  end
545
550
 
546
551
  report_error(
@@ -1042,20 +1047,23 @@ module Lutaml
1042
1047
  next if xml_attr.namespace_uri == XmlBuiltins::NAMESPACE &&
1043
1048
  XmlBuiltins.attribute(xml_attr.name)
1044
1049
 
1045
- # The derivation's wildcard UNION admits: any permitting
1046
- # wildcard covers the attribute, and a strict mode on any
1047
- # admitting wildcard still demands a declaration in the
1048
- # attribute's own namespace.
1050
+ # The derivation's wildcard GROUPS admit: ACROSS groups
1051
+ # (derivation layers) any group admits the attribute — the
1052
+ # extension union; WITHIN a group every wildcard must
1053
+ # admit — same-type wildcards intersect (wildZ013b/c/e).
1049
1054
  admitted = false
1050
1055
  strict_undeclared = false
1051
- wildcards.each do |wildcard|
1052
- next unless wildcard_permits_attribute?(wildcard,
1053
- xml_element,
1054
- xml_attr, repository)
1056
+ wildcards.each do |group|
1057
+ next unless group.all? do |wildcard|
1058
+ wildcard_permits_attribute?(wildcard, xml_element,
1059
+ xml_attr, repository)
1060
+ end
1055
1061
 
1056
1062
  admitted = true
1057
- if wildcard_process_mode(wildcard) == "strict" &&
1063
+ group.each do |wildcard|
1064
+ next unless wildcard_process_mode(wildcard) == "strict" &&
1058
1065
  !attribute_declared?(xml_attr, repository)
1066
+
1059
1067
  strict_undeclared = true
1060
1068
  end
1061
1069
  end
@@ -1106,7 +1114,12 @@ module Lutaml
1106
1114
  # UNION — a base type's wildcard stays in force beside the
1107
1115
  # extension's own (ctH011: ##local base + ##other extension).
1108
1116
  #
1109
- # @return [Array<AnyAttribute>]
1117
+ # @return [Array<Array<AnyAttribute>>] wildcard GROUPS: one
1118
+ # group per derivation layer (the base's groups stay beside
1119
+ # the derived layer — the extension union, wildZ013b/c);
1120
+ # wildcards INSIDE one group are same-type and intersect
1121
+ # (wildZ013e: intersection1's two attributeGroup refs give
1122
+ # set(b, c), rejecting what ##other alone would admit).
1110
1123
  def collect_any_attribute(schema_def, repository = nil,
1111
1124
  xml_element = nil)
1112
1125
  if schema_def.is_a?(Lutaml::Xml::Schema::Xsd::Element)
@@ -1122,21 +1135,21 @@ module Lutaml
1122
1135
  end
1123
1136
  return [] unless schema_def
1124
1137
 
1125
- wildcards = []
1138
+ own = []
1126
1139
  complex_wildcard = schema_def.any_attribute if
1127
1140
  schema_def.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType) &&
1128
1141
  complex_type_wildcard_support?
1129
- wildcards << complex_wildcard if complex_wildcard
1142
+ own << complex_wildcard if complex_wildcard
1130
1143
 
1131
1144
  # A wildcard nested in an attributeGroup DECLARATION reaches
1132
1145
  # the type only through the group's resolution — the type's
1133
1146
  # ref particle carries no children of its own (attgD019).
1134
1147
  Array(schema_def.attribute_group).each do |group|
1135
1148
  Array(group.any_attribute).each do |wildcard|
1136
- wildcards << wildcard
1149
+ own << wildcard
1137
1150
  end
1138
1151
 
1139
- collect_group_wildcards(group, repository, wildcards, 0)
1152
+ collect_group_wildcards(group, repository, own, 0)
1140
1153
  end
1141
1154
 
1142
1155
  CONTENT_KINDS.each do |content_kind|
@@ -1146,22 +1159,31 @@ module Lutaml
1146
1159
  CONTENT_PART_KINDS.each do |part_kind|
1147
1160
  Array(content.public_send(part_kind)).each do |part|
1148
1161
  Array(part.any_attribute).each do |wildcard|
1149
- wildcards << wildcard
1162
+ own << wildcard
1163
+ end
1164
+ # An attributeGroup REF inside the derivation body
1165
+ # carries the wildcard the type presents (wildZ013b:
1166
+ # the extension's attG2-51 ref).
1167
+ Array(part.attribute_group).each do |group_ref|
1168
+ collect_group_wildcards(group_ref, repository, own, 0)
1150
1169
  end
1151
1170
  end
1152
1171
  end
1153
1172
  end
1154
1173
 
1155
1174
  # The base type's wildcard flows into the derived type
1156
- # through extension and restriction alike.
1175
+ # through extension and restriction alike — as its own
1176
+ # layer beside the derived one.
1157
1177
  base = derivation_base(schema_def, repository)
1158
- wildcards.concat(collect_any_attribute(base, repository)) if base
1159
-
1160
- wildcards
1178
+ groups = base ? collect_any_attribute(base, repository) : []
1179
+ groups.unshift(own) unless own.empty?
1180
+ groups
1161
1181
  end
1162
1182
 
1163
1183
  # The wildcards of an attributeGroup reference's DECLARATION,
1164
- # following nested attributeGroup refs (depth-guarded).
1184
+ # following nested attributeGroup refs (depth-guarded). Each
1185
+ # wildcard records its declaring group's effective target
1186
+ # namespace for the ##other evaluation.
1165
1187
  #
1166
1188
  # @return [void]
1167
1189
  def collect_group_wildcards(group, repository, wildcards, depth)
@@ -1175,6 +1197,8 @@ module Lutaml
1175
1197
 
1176
1198
  Array(declaration.any_attribute).each do |wildcard|
1177
1199
  wildcards << wildcard
1200
+ wildcard_owner_tns[wildcard] =
1201
+ repository&.target_namespace_for(declaration)
1178
1202
  end
1179
1203
 
1180
1204
  Array(declaration.attribute_group).each do |nested|
@@ -1214,7 +1238,15 @@ module Lutaml
1214
1238
  def wildcard_permits_attribute?(wildcard, parent, xml_attr,
1215
1239
  repository)
1216
1240
  ns = xml_attr.namespace_uri.to_s
1217
- target = content_target_namespace(parent, repository).to_s
1241
+ # The WILDCARD's own declaration namespace — a chameleon
1242
+ # document's ##other evaluates against its own (absent)
1243
+ # target, not the includer's (wildZ013c).
1244
+ target =
1245
+ if wildcard_owner_tns.key?(wildcard)
1246
+ wildcard_owner_tns[wildcard].to_s
1247
+ else
1248
+ content_target_namespace(parent, repository).to_s
1249
+ end
1218
1250
  case wildcard.namespace.to_s
1219
1251
  when "##any", ""
1220
1252
  true
@@ -1237,6 +1269,16 @@ module Lutaml
1237
1269
  end
1238
1270
  end
1239
1271
 
1272
+ # The effective target namespace of each collected wildcard's
1273
+ # DECLARING attributeGroup (identity-keyed — equal-valued
1274
+ # wildcards eql? together). Untracked wildcards fall back to
1275
+ # the element declaration's namespace.
1276
+ #
1277
+ # @return [Hash]
1278
+ def wildcard_owner_tns
1279
+ @wildcard_owner_tns ||= {}.compare_by_identity
1280
+ end
1281
+
1240
1282
  # Whether a strict-wildcard attribute resolves to a global
1241
1283
  # declaration in the attribute's OWN namespace — the
1242
1284
  # unique-name fallback may not answer for a different
@@ -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
@@ -941,6 +951,10 @@ module Lutaml
941
951
  Array(schema.attribute_group).each do |group|
942
952
  name = group.name.to_s
943
953
  @attribute_groups[name] = group unless name.empty?
954
+ # The group's own effective target namespace — a chameleon
955
+ # document's wildcards evaluate against the includer's
956
+ # (wildZ013c), a named document's against its own.
957
+ @namespaces[group] = namespace unless name.empty?
944
958
  Array(group.attribute).each do |member|
945
959
  index_local_attribute(member, namespace, defaults_schema)
946
960
  end
@@ -1039,6 +1053,13 @@ module Lutaml
1039
1053
  original = @attribute_groups[name]
1040
1054
  @redefined_originals[name] = original if original
1041
1055
  @attribute_groups[name] = group
1056
+ @namespaces[group] = namespace
1057
+ end
1058
+ Array(red.group).each do |group|
1059
+ name = group.name.to_s
1060
+ next if name.empty?
1061
+
1062
+ @redefined_groups[name] = group
1042
1063
  end
1043
1064
  end
1044
1065
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.98"
5
+ VERSION = "1.2.100"
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.98
4
+ version: 1.2.100
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.