lutaml-xsd 1.2.99 → 1.2.101

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: fa20de2fba923a0b6485653e7902c20694898ac8583b90f5e144b11b7ae61fc4
4
- data.tar.gz: ccd4a57412cd1095538a9a72988d9b792f8f3ae213d4c644a401391d32cafcbc
3
+ metadata.gz: 6105bb86be0d4abbb820b3362454d8b05d2323366b35b6d1e6225feafc12dd57
4
+ data.tar.gz: 639b6495bc87a3d3b6a8ec3edac0dfc4457da4af3dba1bef20e4d2c464628c54
5
5
  SHA512:
6
- metadata.gz: 421748a4d525018acc64f0a85f0d84b07320f456017bd06c481bb2cb0b97eeb8b394fbbed64a50f8c3e037277a627d8aa322aabbb2eb9983861f798c78126734
7
- data.tar.gz: 63b4a57e42b8431ab7cec97f0fd015520c991c1ff8ab4017a7f4210f1d9b3f7f3480c8fca5e4c7ddc11079e818bfe4211030ef30cdeb4e6e04714468ca1015d7
6
+ metadata.gz: 7da7d36525dd07c46f9b81e9e1219f1faf5882c871cca810026b76b65f712cf8387e92ecee363a8f0a4ad23b75b42e7b5a1bcd41cf6a8b1c2793812b58dfaf1d
7
+ data.tar.gz: 6475b579cbaa25e35cfcdb497e60c501425337e65676406aec619fbc83a386fb66cf5f94b5e7c4d77a96e79b0ae13bd1818517ca2e10191ae9a31976b5f0fb44
data/TODO.conformance.md CHANGED
@@ -521,7 +521,46 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
521
521
  schF1/P2, stE065/066/096) AND a WHOLESALE 407 regex regression:
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
+ - ANYSIMPLETYPE-WHITESPACE ROUND (2026-11-07): +1 Additional
525
+ (test93160; suite 4627->4628 = 98.55%, pending measure confirm).
526
+ xs:anySimpleType's whiteSpace is PRESERVE — the ur-simple type
527
+ canonicalizes nothing — but the fixed-compare whitespace rule fell
528
+ through to collapse, so whitespace-padded text equaled the fixed
529
+ value. The element- and attribute-side whitespace maps now send
530
+ anySimpleType to preserve; the fixed compare is a RAW-LEXICAL
531
+ compare (xmllint: the padded actual does not match the fixed).
532
+ PARKED same-day classifications (the per-position binding wall —
533
+ the parent-context redesign charter): isDefault079 (two same-named
534
+ locals with DIFFERENT fixed values — the second child binds to the
535
+ second particle; we mis-bind to the first; xmllint validates),
536
+ QFE1700c1 (skip-suppression must follow the matcher's DETERMINISTIC
537
+ assignment — the ref particle takes its e2 and validates its
538
+ content, not the skip-wildcard hereditary escape), addB065
539
+ (xsi:nil=true on non-nillable silent), addB188 (xsi:type-assessed
540
+ undeclared root skips the attribute check). errC007's namespace
541
+ fallback narrowing REVERTED after 5 regressions (addB132/ctZ007/
542
+ elemZ021b/f/elemZ023 lean on the lenient fallback for
543
+ substitution/import shapes) — parked with the same charter.
544
+
524
545
  series — filed leptris-rs#47; moxml 0.6.3 regressed 5 attribute
546
+ - WILDCARD-LAYERING ROUND (2026-11-07): +3 Wildcards (wildZ013b/c
547
+ valid, wildZ013e invalid; suite 4624->4627 = 98.57%, zero
548
+ regressions, rspec green). THREE defects: (1) attributeGroup refs
549
+ nested in content parts never contributed their anyAttribute
550
+ wildcards (wildZ013b — the extension's attG2-51 ref); (2) the
551
+ derivation wildcard list admitted with plain UNION semantics where
552
+ same-type wildcards must INTERSECT (wildZ013e: intersection1's
553
+ ##other + ##local b c give set(b, c) — absent-ns attributes fail
554
+ ##other) — collect_any_attribute now returns one GROUP per
555
+ derivation layer: groups union (the extension union, ctH011
556
+ unchanged), members intersect; (3) the chameleon import's ##other
557
+ evaluated against the INCLUDER's target namespace — the
558
+ per-wildcard owner tns (indexed for attributeGroup declarations
559
+ and redefine bodies now) evaluates a chameleon's ##other against
560
+ its own ABSENT target (wildZ013c's ##local b c + ##other(not-
561
+ absent) admit everything the instance carries). Family: Wildcards
562
+ + Attribute clean; AttributeGroup 14 = the parked moxml#522 set.
563
+
525
564
  cases (addB059/196c/197c, attO009/011) — filed moxml#529. THE
526
565
  - REDEFINE-GROUP ROUND (2026-11-07): +2 ModelGroups (mgO006,
527
566
  mgO034; suite 4622->4624 = 98.46%, zero regressions, rspec
@@ -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(
@@ -648,7 +653,9 @@ module Lutaml
648
653
  return :preserve unless builtin_type_name?(reference)
649
654
 
650
655
  local = reference.split(":").last
651
- return :preserve if local == "string"
656
+ # anySimpleType's whiteSpace is PRESERVE — the ur-simple
657
+ # type canonicalizes nothing.
658
+ return :preserve if ["string", "anySimpleType"].include?(local)
652
659
  return :replace if local == "normalizedString"
653
660
 
654
661
  :collapse
@@ -1042,20 +1049,23 @@ module Lutaml
1042
1049
  next if xml_attr.namespace_uri == XmlBuiltins::NAMESPACE &&
1043
1050
  XmlBuiltins.attribute(xml_attr.name)
1044
1051
 
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.
1052
+ # The derivation's wildcard GROUPS admit: ACROSS groups
1053
+ # (derivation layers) any group admits the attribute — the
1054
+ # extension union; WITHIN a group every wildcard must
1055
+ # admit — same-type wildcards intersect (wildZ013b/c/e).
1049
1056
  admitted = false
1050
1057
  strict_undeclared = false
1051
- wildcards.each do |wildcard|
1052
- next unless wildcard_permits_attribute?(wildcard,
1053
- xml_element,
1054
- xml_attr, repository)
1058
+ wildcards.each do |group|
1059
+ next unless group.all? do |wildcard|
1060
+ wildcard_permits_attribute?(wildcard, xml_element,
1061
+ xml_attr, repository)
1062
+ end
1055
1063
 
1056
1064
  admitted = true
1057
- if wildcard_process_mode(wildcard) == "strict" &&
1065
+ group.each do |wildcard|
1066
+ next unless wildcard_process_mode(wildcard) == "strict" &&
1058
1067
  !attribute_declared?(xml_attr, repository)
1068
+
1059
1069
  strict_undeclared = true
1060
1070
  end
1061
1071
  end
@@ -1106,7 +1116,12 @@ module Lutaml
1106
1116
  # UNION — a base type's wildcard stays in force beside the
1107
1117
  # extension's own (ctH011: ##local base + ##other extension).
1108
1118
  #
1109
- # @return [Array<AnyAttribute>]
1119
+ # @return [Array<Array<AnyAttribute>>] wildcard GROUPS: one
1120
+ # group per derivation layer (the base's groups stay beside
1121
+ # the derived layer — the extension union, wildZ013b/c);
1122
+ # wildcards INSIDE one group are same-type and intersect
1123
+ # (wildZ013e: intersection1's two attributeGroup refs give
1124
+ # set(b, c), rejecting what ##other alone would admit).
1110
1125
  def collect_any_attribute(schema_def, repository = nil,
1111
1126
  xml_element = nil)
1112
1127
  if schema_def.is_a?(Lutaml::Xml::Schema::Xsd::Element)
@@ -1122,21 +1137,21 @@ module Lutaml
1122
1137
  end
1123
1138
  return [] unless schema_def
1124
1139
 
1125
- wildcards = []
1140
+ own = []
1126
1141
  complex_wildcard = schema_def.any_attribute if
1127
1142
  schema_def.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType) &&
1128
1143
  complex_type_wildcard_support?
1129
- wildcards << complex_wildcard if complex_wildcard
1144
+ own << complex_wildcard if complex_wildcard
1130
1145
 
1131
1146
  # A wildcard nested in an attributeGroup DECLARATION reaches
1132
1147
  # the type only through the group's resolution — the type's
1133
1148
  # ref particle carries no children of its own (attgD019).
1134
1149
  Array(schema_def.attribute_group).each do |group|
1135
1150
  Array(group.any_attribute).each do |wildcard|
1136
- wildcards << wildcard
1151
+ own << wildcard
1137
1152
  end
1138
1153
 
1139
- collect_group_wildcards(group, repository, wildcards, 0)
1154
+ collect_group_wildcards(group, repository, own, 0)
1140
1155
  end
1141
1156
 
1142
1157
  CONTENT_KINDS.each do |content_kind|
@@ -1146,22 +1161,31 @@ module Lutaml
1146
1161
  CONTENT_PART_KINDS.each do |part_kind|
1147
1162
  Array(content.public_send(part_kind)).each do |part|
1148
1163
  Array(part.any_attribute).each do |wildcard|
1149
- wildcards << wildcard
1164
+ own << wildcard
1165
+ end
1166
+ # An attributeGroup REF inside the derivation body
1167
+ # carries the wildcard the type presents (wildZ013b:
1168
+ # the extension's attG2-51 ref).
1169
+ Array(part.attribute_group).each do |group_ref|
1170
+ collect_group_wildcards(group_ref, repository, own, 0)
1150
1171
  end
1151
1172
  end
1152
1173
  end
1153
1174
  end
1154
1175
 
1155
1176
  # The base type's wildcard flows into the derived type
1156
- # through extension and restriction alike.
1177
+ # through extension and restriction alike — as its own
1178
+ # layer beside the derived one.
1157
1179
  base = derivation_base(schema_def, repository)
1158
- wildcards.concat(collect_any_attribute(base, repository)) if base
1159
-
1160
- wildcards
1180
+ groups = base ? collect_any_attribute(base, repository) : []
1181
+ groups.unshift(own) unless own.empty?
1182
+ groups
1161
1183
  end
1162
1184
 
1163
1185
  # The wildcards of an attributeGroup reference's DECLARATION,
1164
- # following nested attributeGroup refs (depth-guarded).
1186
+ # following nested attributeGroup refs (depth-guarded). Each
1187
+ # wildcard records its declaring group's effective target
1188
+ # namespace for the ##other evaluation.
1165
1189
  #
1166
1190
  # @return [void]
1167
1191
  def collect_group_wildcards(group, repository, wildcards, depth)
@@ -1175,6 +1199,8 @@ module Lutaml
1175
1199
 
1176
1200
  Array(declaration.any_attribute).each do |wildcard|
1177
1201
  wildcards << wildcard
1202
+ wildcard_owner_tns[wildcard] =
1203
+ repository&.target_namespace_for(declaration)
1178
1204
  end
1179
1205
 
1180
1206
  Array(declaration.attribute_group).each do |nested|
@@ -1214,7 +1240,15 @@ module Lutaml
1214
1240
  def wildcard_permits_attribute?(wildcard, parent, xml_attr,
1215
1241
  repository)
1216
1242
  ns = xml_attr.namespace_uri.to_s
1217
- target = content_target_namespace(parent, repository).to_s
1243
+ # The WILDCARD's own declaration namespace — a chameleon
1244
+ # document's ##other evaluates against its own (absent)
1245
+ # target, not the includer's (wildZ013c).
1246
+ target =
1247
+ if wildcard_owner_tns.key?(wildcard)
1248
+ wildcard_owner_tns[wildcard].to_s
1249
+ else
1250
+ content_target_namespace(parent, repository).to_s
1251
+ end
1218
1252
  case wildcard.namespace.to_s
1219
1253
  when "##any", ""
1220
1254
  true
@@ -1237,6 +1271,16 @@ module Lutaml
1237
1271
  end
1238
1272
  end
1239
1273
 
1274
+ # The effective target namespace of each collected wildcard's
1275
+ # DECLARING attributeGroup (identity-keyed — equal-valued
1276
+ # wildcards eql? together). Untracked wildcards fall back to
1277
+ # the element declaration's namespace.
1278
+ #
1279
+ # @return [Hash]
1280
+ def wildcard_owner_tns
1281
+ @wildcard_owner_tns ||= {}.compare_by_identity
1282
+ end
1283
+
1240
1284
  # Whether a strict-wildcard attribute resolves to a global
1241
1285
  # declaration in the attribute's OWN namespace — the
1242
1286
  # unique-name fallback may not answer for a different
@@ -488,7 +488,10 @@ module Lutaml
488
488
  end
489
489
 
490
490
  case local
491
- when "string"
491
+ when "string", "anySimpleType"
492
+ # anySimpleType's whiteSpace is PRESERVE (the ur-simple
493
+ # type canonicalizes nothing) — a fixed compare against
494
+ # it compares the raw lexical (test93160).
492
495
  :preserve
493
496
  when "normalizedString"
494
497
  :replace
@@ -951,6 +951,10 @@ module Lutaml
951
951
  Array(schema.attribute_group).each do |group|
952
952
  name = group.name.to_s
953
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?
954
958
  Array(group.attribute).each do |member|
955
959
  index_local_attribute(member, namespace, defaults_schema)
956
960
  end
@@ -1049,6 +1053,7 @@ module Lutaml
1049
1053
  original = @attribute_groups[name]
1050
1054
  @redefined_originals[name] = original if original
1051
1055
  @attribute_groups[name] = group
1056
+ @namespaces[group] = namespace
1052
1057
  end
1053
1058
  Array(red.group).each do |group|
1054
1059
  name = group.name.to_s
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.99"
5
+ VERSION = "1.2.101"
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.99
4
+ version: 1.2.101
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.