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 +4 -4
- data/TODO.conformance.md +39 -0
- data/lib/lutaml/xsd/validation/rules/attribute_validation_rule.rb +69 -25
- data/lib/lutaml/xsd/validation/rules/type_validation_rule.rb +4 -1
- data/lib/lutaml/xsd/validation/schema_definition_resolver.rb +5 -0
- data/lib/lutaml/xsd/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6105bb86be0d4abbb820b3362454d8b05d2323366b35b6d1e6225feafc12dd57
|
|
4
|
+
data.tar.gz: 639b6495bc87a3d3b6a8ec3edac0dfc4457da4af3dba1bef20e4d2c464628c54
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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
|
-
|
|
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
|
|
1046
|
-
#
|
|
1047
|
-
#
|
|
1048
|
-
#
|
|
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 |
|
|
1052
|
-
next unless
|
|
1053
|
-
|
|
1054
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1151
|
+
own << wildcard
|
|
1137
1152
|
end
|
|
1138
1153
|
|
|
1139
|
-
collect_group_wildcards(group, repository,
|
|
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
|
-
|
|
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
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
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
|
-
|
|
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
|
data/lib/lutaml/xsd/version.rb
CHANGED