lutaml-xsd 1.2.103 → 1.2.105

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: 0406cd7f1ca030db5b4c6db63f060fdaae3981f61d2913f3552c510129f80b8c
4
- data.tar.gz: 067f44365c98c7a9b3fd221c74d35965d5e628b3cb58f788e7210bd8a8cc6964
3
+ metadata.gz: 1b6818402b9251af19a59e3a7858a54a9acd85a2f1b6705ba6ffaf1346ad7979
4
+ data.tar.gz: 774c04eb4a361f5b5d076a4228280968f7c85e4b82a9fae996056727d21f7ab4
5
5
  SHA512:
6
- metadata.gz: d7b9a1f01944bfe42b257e750226f2e9b200fbe3a30fe14ac834f3b1b7fdd675a12afb77764eaf821e09662674788ecf764064516477e26df394da4ba8b66ac2
7
- data.tar.gz: 8dc0ac9729456a8903c6a2f70c4db8d1d2c7704076654ac173c4450aa089c76d3369a48f61d1638c210e26cd5b94584cebeff2af4700bdf3964b587136082183
6
+ metadata.gz: f04e67e032a0b304af390e8404105f588852ed0d59f306aa10f94394169aae8a8416748aa141417ffa21f2b81199a89d463a68d2baea11dcd8fdf2507fcc4e25
7
+ data.tar.gz: f56003936d0e805e72e0e490b5065e32d6bd1aeb9d18dfbe38a5009a8ec9fc42ca4a8aab70acfee5fac48e5ce5f72e2c3b640c3eef27e00e256a8b59133014db
data/TODO.conformance.md CHANGED
@@ -517,7 +517,37 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
517
517
  layering), full type-redefine body semantics.
518
518
  - RIDE-407 PIN-BACK (2026-11-05): the leptris 1.9.407.0 + moxml
519
519
  0.6.3 + lutaml-model 0.8.166 train carried fixes (the FULL #45
520
+ - LAX-OBIGATION ROUND (2026-11-08, parent-context round D): +5
521
+ DataTypes (duration028/029/030, dateTime013, gMonthDay006; suite
522
+ 4631->4636 = 98.72%, pending measure confirm). THE LAX WILDCARD
523
+ OBLIGATION (XSD 1.0 §3.10.4) now runs: a wildcard-governed
524
+ attribute whose declaration IS AVAILABLE (resolved in the
525
+ attribute's OWN namespace, checked against the declaration's
526
+ expected namespace — the exact-ns discipline that killed the
527
+ first attempt's name-based mis-typing) is VALIDATED against it.
528
+ duration028: the lax-governed "P" hits the global xs:duration
529
+ declaration and rejects. The unexpected-attribute check splits
530
+ into admission / strict-undeclared reporting / the obligation.
531
+ The prior dead-end's regression shapes (idF/G comps, ctZ011_b,
532
+ elemZ014, schQ1, wildZ004) re-verified clean. PARKED REMAINDER:
533
+ QFE1700c1 (matcher assignment), addB188 (ComplexType-capability
534
+ sweep), schA1/D10 (child-value binding).
535
+
520
536
  stE legs, the #522 attgC four + attgD mostly + attJ018 +
537
+ - PARENT-CONTEXT ROUND C (2026-11-08): +1 Additional (addB065;
538
+ suite 4630->4631 = 98.61%, pending measure confirm). A declaration
539
+ carrying a FIXED value constraint rejects xsi:nil=true outright
540
+ (XSD 1.0 §4.2.3 as the errata reads it; xmllint: "cannot be
541
+ 'nilled' because there is a fixed value constraint defined for
542
+ it") — the nil-true branch now reports xsi_nil_with_fixed and
543
+ treats the element as nilled-handled. PARKED same-day: addB188
544
+ (an undeclared root anchored by xsi:type must assess against the
545
+ named type — the override-type dispatch was TRIED and reverted:
546
+ constraint-category rules assume Element schema_defs and crash on
547
+ ComplexType; the fix needs a per-rule ComplexType-capability
548
+ audit, a sibling of the parent-context charter). addB187's valid
549
+ twin re-verified after the revert.
550
+
521
551
  schF1/P2, stE065/066/096) AND a WHOLESALE 407 regex regression:
522
552
  - PARENT-CONTEXT ROUND B (2026-11-08): +1 Additional (isDefault079;
523
553
  suite 4629->4630 = 98.59%, zero regressions, rspec green).
@@ -1032,56 +1032,19 @@ module Lutaml
1032
1032
  wildcards: [], repository: nil,
1033
1033
  schema_element: nil)
1034
1034
  xml_attrs.each do |xml_attr|
1035
- # Skip xmlns attributes
1036
- next if xml_attr.name == "xmlns" ||
1037
- xml_attr.prefix == "xmlns"
1038
-
1039
- # Skip xsi attributes
1040
- next if xml_attr.namespace_uri ==
1041
- "http://www.w3.org/2001/XMLSchema-instance"
1035
+ next if spec_namespace_attribute?(xml_attr)
1042
1036
 
1043
1037
  schema_attr = find_schema_attribute(schema_attrs, xml_attr,
1044
1038
  repository, schema_element)
1045
1039
  next if schema_attr
1046
1040
 
1047
- # xml:lang and friends are declared by the spec, not by
1048
- # the schema document.
1049
- next if xml_attr.namespace_uri == XmlBuiltins::NAMESPACE &&
1050
- XmlBuiltins.attribute(xml_attr.name)
1051
-
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).
1056
- admitted = false
1057
- strict_undeclared = false
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
1063
-
1064
- admitted = true
1065
- group.each do |wildcard|
1066
- next unless wildcard_process_mode(wildcard) == "strict" &&
1067
- !attribute_declared?(xml_attr, repository)
1068
-
1069
- strict_undeclared = true
1070
- end
1071
- end
1041
+ admitted, strict_undeclared =
1042
+ wildcard_admission(xml_attr, xml_element, wildcards,
1043
+ repository)
1072
1044
 
1073
1045
  if admitted
1074
- if strict_undeclared
1075
- report_error(
1076
- collector,
1077
- code: "wildcard_undeclared_attribute",
1078
- message: "Attribute '#{xml_attr.qualified_name}' " \
1079
- "matches xs:anyAttribute with " \
1080
- "processContents=strict but is not declared",
1081
- location: xml_element.xpath,
1082
- context: { attribute: xml_attr.qualified_name },
1083
- )
1084
- end
1046
+ report_wildcard_finding(xml_element, xml_attr, collector,
1047
+ strict_undeclared, repository)
1085
1048
  next
1086
1049
  end
1087
1050
 
@@ -1100,6 +1063,78 @@ module Lutaml
1100
1063
  end
1101
1064
  end
1102
1065
 
1066
+ # xmlns declarations, xsi, and the xml: builtins (lang, base,
1067
+ # space — declared by the spec, not by the schema document)
1068
+ # are not content.
1069
+ #
1070
+ # @return [Boolean]
1071
+ def spec_namespace_attribute?(xml_attr)
1072
+ return true if xml_attr.name == "xmlns" ||
1073
+ xml_attr.prefix == "xmlns"
1074
+
1075
+ return true if xml_attr.namespace_uri == XSI_NAMESPACE
1076
+
1077
+ xml_attr.namespace_uri == XmlBuiltins::NAMESPACE &&
1078
+ XmlBuiltins.attribute(xml_attr.name)
1079
+ end
1080
+
1081
+ # The derivation's wildcard GROUPS admit: ACROSS groups
1082
+ # (derivation layers) any group admits the attribute — the
1083
+ # extension union; WITHIN a group every wildcard must admit —
1084
+ # same-type wildcards intersect (wildZ013b/c/e). A strict
1085
+ # wildcard in an admitting group still demands a declaration.
1086
+ #
1087
+ # @return [Array(Boolean, Boolean)] [admitted, strict_undeclared]
1088
+ def wildcard_admission(xml_attr, xml_element, wildcards, repository)
1089
+ admitted = false
1090
+ strict_undeclared = false
1091
+ wildcards.each do |group|
1092
+ next unless group.all? do |wildcard|
1093
+ wildcard_permits_attribute?(wildcard, xml_element,
1094
+ xml_attr, repository)
1095
+ end
1096
+
1097
+ admitted = true
1098
+ group.each do |wildcard|
1099
+ next unless wildcard_process_mode(wildcard) == "strict" &&
1100
+ !attribute_declared?(xml_attr, repository)
1101
+
1102
+ strict_undeclared = true
1103
+ end
1104
+ end
1105
+ [admitted, strict_undeclared]
1106
+ end
1107
+
1108
+ # An admitted wildcard attribute reports the strict-undeclared
1109
+ # finding when strict demanded a declaration, then runs the
1110
+ # lax obligation (XSD 1.0 §3.10.4): a wildcard-governed
1111
+ # attribute whose declaration IS available (in the attribute's
1112
+ # own namespace) is validated against it — duration028: the
1113
+ # lax-governed "P" must still hit its global xs:duration
1114
+ # declaration.
1115
+ #
1116
+ # @return [void]
1117
+ def report_wildcard_finding(xml_element, xml_attr, collector,
1118
+ strict_undeclared, repository)
1119
+ if strict_undeclared
1120
+ report_error(
1121
+ collector,
1122
+ code: "wildcard_undeclared_attribute",
1123
+ message: "Attribute '#{xml_attr.qualified_name}' " \
1124
+ "matches xs:anyAttribute with " \
1125
+ "processContents=strict but is not declared",
1126
+ location: xml_element.xpath,
1127
+ context: { attribute: xml_attr.qualified_name },
1128
+ )
1129
+ end
1130
+
1131
+ found = wildcard_declaration(xml_attr, repository)
1132
+ return unless found
1133
+
1134
+ validate_attribute_value(xml_element, xml_attr, found,
1135
+ collector, repository: repository)
1136
+ end
1137
+
1103
1138
  # Whether the loaded lutaml-model parses xs:anyAttribute on
1104
1139
  # complexType (the mapping landed after 0.8.121); probed once
1105
1140
  # with a minimal schema.
@@ -1290,14 +1325,28 @@ module Lutaml
1290
1325
  def attribute_declared?(xml_attr, repository)
1291
1326
  return true if repository.nil?
1292
1327
 
1328
+ !wildcard_declaration(xml_attr, repository).nil?
1329
+ end
1330
+
1331
+ # The global declaration the wildcard-governed attribute
1332
+ # resolves to, resolved in the attribute's OWN namespace and
1333
+ # checked against the declaration's expected namespace
1334
+ # (duration028's lax obligation uses it for value validation).
1335
+ #
1336
+ # @return [Lutaml::Xml::Schema::Xsd::Attribute, nil]
1337
+ def wildcard_declaration(xml_attr, repository)
1338
+ return nil if repository.nil?
1339
+
1293
1340
  declaration = repository.resolve_attribute(
1294
1341
  xml_attr.name, xml_attr.namespace_uri
1295
1342
  )
1296
- return false unless declaration
1343
+ return nil unless declaration
1297
1344
 
1298
1345
  expected = repository.expected_attribute_namespace(declaration)
1299
- expected.nil? ||
1300
- expected == xml_attr.namespace_uri.to_s
1346
+ if expected.nil? ||
1347
+ expected == xml_attr.namespace_uri.to_s
1348
+ declaration
1349
+ end
1301
1350
  end
1302
1351
 
1303
1352
  # Target namespace of the schema owning the parent's declaration.
@@ -333,6 +333,22 @@ module Lutaml
333
333
  return true
334
334
  end
335
335
 
336
+ # A fixed value constraint forbids nilled elements
337
+ # outright (addB065; xmllint: "cannot be 'nilled' because
338
+ # there is a fixed value constraint").
339
+ unless schema_element.fixed.to_s.empty?
340
+ report_error(
341
+ collector,
342
+ code: "xsi_nil_with_fixed",
343
+ message: "Element '#{xml_element.name}' cannot be " \
344
+ "nilled because there is a fixed value " \
345
+ "constraint defined for it",
346
+ location: xml_element.xpath,
347
+ context: { element: xml_element.name },
348
+ )
349
+ return true
350
+ end
351
+
336
352
  if xml_element.children.empty? &&
337
353
  xml_element.text_content.to_s.strip.empty?
338
354
  return true
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.103"
5
+ VERSION = "1.2.105"
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.103
4
+ version: 1.2.105
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.