lutaml-xsd 1.2.96 → 1.2.98
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 +35 -0
- data/lib/lutaml/xsd/validation/rule_registry.rb +2 -0
- data/lib/lutaml/xsd/validation/rules/identity_constraints_rule.rb +106 -0
- data/lib/lutaml/xsd/validation/rules/idref_resolution_rule.rb +229 -0
- data/lib/lutaml/xsd/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e129470c8c939e17b19e748ffaebf593f7f3909876fbe05e1b733e1129f448ba
|
|
4
|
+
data.tar.gz: '03015085efe53c4dca6dec3bc5115d9081b42a24c2f758b19c4c3424b672521f'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4e1be4de4f925cb152fa5f69e2cb57fb42d9337ab37628b71314ab0e3bc7a5d10da9cf829173a78303c0e8e495682286bb9ecf4bde0d72056324d6e572d309cc
|
|
7
|
+
data.tar.gz: ae47a5ca4b9bc803c7e7c35aaeb0a9e8a35e9610bddacdd82d14b269310863f91d64a9f59f1cd9f0014ea72dd0040f975098feccd30914fc6e7cf053845a9b91
|
data/TODO.conformance.md
CHANGED
|
@@ -524,7 +524,42 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
|
|
|
524
524
|
series — filed leptris-rs#47; moxml 0.6.3 regressed 5 attribute
|
|
525
525
|
cases (addB059/196c/197c, attO009/011) — filed moxml#529. THE
|
|
526
526
|
STACK IS PINNED BACK to the known-good 1.9.406.0/0.6.2/0.8.161
|
|
527
|
+
- SKIP-WILDCARD-FIELD ROUND (2026-11-07): +1 IC (idZ015; suite
|
|
528
|
+
4621->4622 = 98.42%, zero regressions, rspec green). THE LAST IC
|
|
529
|
+
SINGLETON — the idK/idZ family is now CLEAN (all six roots fixed
|
|
530
|
+
across the four rounds). An attribute admitted by a
|
|
531
|
+
processContents=skip wildcard is NOT ASSESSED, so it supplies no
|
|
532
|
+
identity-constraint field value: the field treats it as absent and
|
|
533
|
+
a key whose fields do not all evaluate is violated (idZ015: foo's
|
|
534
|
+
##any skip anyAttribute + key field @bar; xmllint: "Not all fields
|
|
535
|
+
of key identity-constraint evaluate to a node"). The skip check
|
|
536
|
+
walks the selector node's declaration anyAttribute wildcards
|
|
537
|
+
(own + content parts + attributeGroup members, depth 3) and the
|
|
538
|
+
namespace constraint reads the attribute's URI from the MOXML
|
|
539
|
+
element wrapper — xpath result attributes are ADAPTER objects
|
|
540
|
+
(leptris ResultAttr carries no namespace). GOTCHA: the first
|
|
541
|
+
implementation read node.namespace and CRASHED under leptris —
|
|
542
|
+
the suite probe "passed" as CRASH-AS-INVALID, caught by writing
|
|
543
|
+
the rule-level spec FIRST (rule_execution_error instead of the
|
|
544
|
+
finding). Suite verdicts from crashes are not fixes; assert the
|
|
545
|
+
finding code.
|
|
546
|
+
|
|
527
547
|
(98.28% restored, zero regressions vs the 406 baseline). The
|
|
548
|
+
- IDREF-RESOLUTION ROUND (2026-11-07): +1 IC (idZ012; suite
|
|
549
|
+
4620->4621 = 98.40%, zero regressions, rspec green). Every
|
|
550
|
+
IDREF/IDREFS value must match an ID in the document (XSD 1.0
|
|
551
|
+
§3.3.3) — the check did not exist at all. IdrefResolutionRule
|
|
552
|
+
(identity category, root-scoped two-phase scan beside
|
|
553
|
+
IdUniquenessRule) collects every document ID (element text +
|
|
554
|
+
attributes), then checks IDREF/IDREFS values from instance
|
|
555
|
+
attributes, element text, AND the declaration's fixed/default
|
|
556
|
+
supply when the instance omits the attribute — a defaulted IDREFS
|
|
557
|
+
still references (idZ012: drefs type="xs:IDREFS" default="abc"
|
|
558
|
+
against a document with no ID). IDREFS tokenizes; every token must
|
|
559
|
+
resolve; the two-phase order makes forward references valid.
|
|
560
|
+
Remaining IC singleton: idZ015 (a skip-wildcard-governed attribute
|
|
561
|
+
supplies no IC field value).
|
|
562
|
+
|
|
528
563
|
407 wins ride again when #47 and #529 land. NET: no score
|
|
529
564
|
- ID-VALUE-CONSTRAINT ROUND (2026-11-07): +1 IC (idZ011; suite
|
|
530
565
|
4619->4620 = 98.38%, zero regressions, rspec green). Value
|
|
@@ -8,6 +8,7 @@ require_relative "rules/occurrence_validation_rule"
|
|
|
8
8
|
require_relative "rules/content_model_validation_rule"
|
|
9
9
|
require_relative "rules/identity_constraints_rule"
|
|
10
10
|
require_relative "rules/id_uniqueness_rule"
|
|
11
|
+
require_relative "rules/idref_resolution_rule"
|
|
11
12
|
|
|
12
13
|
module Lutaml
|
|
13
14
|
module Xsd
|
|
@@ -63,6 +64,7 @@ module Lutaml
|
|
|
63
64
|
if config.feature_enabled?(:validate_identity_constraints)
|
|
64
65
|
registry.register(Rules::IdentityConstraintsRule.new)
|
|
65
66
|
registry.register(Rules::IdUniquenessRule.new)
|
|
67
|
+
registry.register(Rules::IdrefResolutionRule.new)
|
|
66
68
|
end
|
|
67
69
|
registry
|
|
68
70
|
end
|
|
@@ -128,6 +128,14 @@ module Lutaml
|
|
|
128
128
|
ambiguous = true if matched.size > 1
|
|
129
129
|
values << if matched.first.nil?
|
|
130
130
|
field_supply_value(node, field, repository)
|
|
131
|
+
elsif !matched.first.is_a?(Moxml::Element) &&
|
|
132
|
+
skip_governed_attribute?(node, matched.first,
|
|
133
|
+
repository)
|
|
134
|
+
# A skip-wildcard-governed attribute is not
|
|
135
|
+
# assessed, so it supplies no identity-
|
|
136
|
+
# constraint value: the field treats it as
|
|
137
|
+
# absent (idZ015).
|
|
138
|
+
nil
|
|
131
139
|
elsif matched.first.is_a?(Moxml::Element) &&
|
|
132
140
|
field_node_non_simple?(
|
|
133
141
|
matched.first, constraint, raws[index],
|
|
@@ -337,6 +345,104 @@ module Lutaml
|
|
|
337
345
|
repository.declared_attribute_supply(parent_type, attr_local)
|
|
338
346
|
end
|
|
339
347
|
|
|
348
|
+
# Whether the instance attribute is governed by a SKIP
|
|
349
|
+
# wildcard on the selector node's declaration: a skip-
|
|
350
|
+
# governed attribute is not assessed, so it supplies no
|
|
351
|
+
# identity-constraint field value (idZ015).
|
|
352
|
+
#
|
|
353
|
+
# @return [Boolean]
|
|
354
|
+
def skip_governed_attribute?(element_node, attribute_node,
|
|
355
|
+
repository)
|
|
356
|
+
declaration = repository&.resolve(element_node.name,
|
|
357
|
+
element_node.namespace_uri)
|
|
358
|
+
return false unless declaration
|
|
359
|
+
|
|
360
|
+
type = declaration.complex_type ||
|
|
361
|
+
repository.resolve_type(declaration)
|
|
362
|
+
return false unless type.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
|
|
363
|
+
|
|
364
|
+
target_ns = repository.target_namespace_for(declaration)
|
|
365
|
+
attribute_ns = attribute_namespace(element_node, attribute_node)
|
|
366
|
+
attribute_skip_wildcards(type, repository, 0).any? do |wildcard|
|
|
367
|
+
wildcard_process_mode(wildcard) == "skip" &&
|
|
368
|
+
wildcard_admits_namespace?(wildcard, attribute_ns, target_ns)
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
# The attribute's namespace URI: the xpath result nodes are
|
|
373
|
+
# adapter objects (leptris ResultAttr carries no namespace),
|
|
374
|
+
# so the name-matched attribute on the MOXML element wrapper
|
|
375
|
+
# resolves it.
|
|
376
|
+
#
|
|
377
|
+
# @return [String]
|
|
378
|
+
def attribute_namespace(element_node, attribute_node)
|
|
379
|
+
found = element_node.attributes.find do |candidate|
|
|
380
|
+
candidate.name == attribute_node.name
|
|
381
|
+
end
|
|
382
|
+
found&.namespace&.uri.to_s
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# The anyAttribute wildcards reachable from the type: its own,
|
|
386
|
+
# content-part bodies, and attributeGroup members (nested
|
|
387
|
+
# refs depth-guarded).
|
|
388
|
+
#
|
|
389
|
+
# @return [Array<Lutaml::Xml::Schema::Xsd::AnyAttribute>]
|
|
390
|
+
def attribute_skip_wildcards(type, repository, depth)
|
|
391
|
+
return [] if depth > 3
|
|
392
|
+
|
|
393
|
+
wildcards = Array(type.any_attribute)
|
|
394
|
+
Array(type.attribute_group).each do |group|
|
|
395
|
+
wildcards.concat(Array(group.any_attribute))
|
|
396
|
+
local = (group.ref || group.name).to_s.split(":").last
|
|
397
|
+
declaration = local && repository.resolve_attribute_group(local)
|
|
398
|
+
if declaration
|
|
399
|
+
wildcards.concat(attribute_skip_wildcards(declaration,
|
|
400
|
+
repository,
|
|
401
|
+
depth + 1))
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
content_kinds = %i[complex_content simple_content]
|
|
405
|
+
part_kinds = %i[extension restriction]
|
|
406
|
+
content_kinds.each do |content_kind|
|
|
407
|
+
content = type.public_send(content_kind)
|
|
408
|
+
next unless content
|
|
409
|
+
|
|
410
|
+
part_kinds.each do |part_kind|
|
|
411
|
+
Array(content.public_send(part_kind)).each do |part|
|
|
412
|
+
wildcards.concat(Array(part.any_attribute))
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
wildcards
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
# Whether the wildcard's namespace constraint admits the
|
|
420
|
+
# attribute's namespace (mirrors WildcardScope#wildcard_permits?
|
|
421
|
+
# for attribute nodes, against the declaration's target
|
|
422
|
+
# namespace).
|
|
423
|
+
#
|
|
424
|
+
# @return [Boolean]
|
|
425
|
+
def wildcard_admits_namespace?(wildcard, uri, target_ns)
|
|
426
|
+
case wildcard.namespace.to_s
|
|
427
|
+
when "##any", ""
|
|
428
|
+
true
|
|
429
|
+
when "##other"
|
|
430
|
+
!uri.empty? && uri != target_ns.to_s
|
|
431
|
+
when "##local"
|
|
432
|
+
uri.empty?
|
|
433
|
+
when "##targetNamespace"
|
|
434
|
+
uri == target_ns.to_s
|
|
435
|
+
else
|
|
436
|
+
wildcard.namespace.to_s.split(/\s+/).any? do |entry|
|
|
437
|
+
case entry
|
|
438
|
+
when "##local" then uri.empty?
|
|
439
|
+
when "##targetNamespace" then uri == target_ns.to_s
|
|
440
|
+
else entry == uri
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
340
446
|
# Whether an element field's node supplies no identity value:
|
|
341
447
|
# it has element children, is declared non-simple (complex
|
|
342
448
|
# content or xsd:anyType — the typeless default), or carries a
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../validation_rule"
|
|
4
|
+
|
|
5
|
+
module Lutaml
|
|
6
|
+
module Xsd
|
|
7
|
+
module Validation
|
|
8
|
+
module Rules
|
|
9
|
+
# IdrefResolutionRule enforces built-in xs:IDREF(S) resolution
|
|
10
|
+
#
|
|
11
|
+
# XSD 1.0 §3.3.3: every IDREF/IDREFS value must match the value
|
|
12
|
+
# of some ID in the document. Values come from instance
|
|
13
|
+
# attributes, element text typed IDREF(S), AND a declaration's
|
|
14
|
+
# fixed/default supply when the instance omits the attribute —
|
|
15
|
+
# a defaulted IDREFS still references (idZ012: drefs
|
|
16
|
+
# type="xs:IDREFS" default="abc" against a document declaring
|
|
17
|
+
# no ID). IDREFS values tokenize on whitespace; every token
|
|
18
|
+
# must resolve. The scan is two-phase (all IDs first, then all
|
|
19
|
+
# references), so forward references resolve.
|
|
20
|
+
class IdrefResolutionRule < ValidationRule
|
|
21
|
+
def category
|
|
22
|
+
:identity
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def description
|
|
26
|
+
"Validates built-in xs:IDREF(S) values resolve to document IDs"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def validate(xml_element, schema_element, collector,
|
|
30
|
+
repository: nil)
|
|
31
|
+
return unless repository
|
|
32
|
+
return unless
|
|
33
|
+
schema_element.is_a?(Lutaml::Xml::Schema::Xsd::Element)
|
|
34
|
+
|
|
35
|
+
# The walk invokes the rule per element and per category;
|
|
36
|
+
# the document is scanned exactly once, from the first
|
|
37
|
+
# (root) invocation — element wrappers are not
|
|
38
|
+
# identity-stable across passes.
|
|
39
|
+
return if @scanned
|
|
40
|
+
|
|
41
|
+
@scanned = true
|
|
42
|
+
ids = collect_ids(xml_element, repository)
|
|
43
|
+
check_references(xml_element, ids, collector, repository)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
# Phase 1: every ID value in the document (element text and
|
|
49
|
+
# attributes). Mirrors IdUniquenessRule's walk — IDs come
|
|
50
|
+
# from instances only; a declaration cannot supply an ID that
|
|
51
|
+
# the document does not contain.
|
|
52
|
+
#
|
|
53
|
+
# @return [Set<String>]
|
|
54
|
+
def collect_ids(element, repository)
|
|
55
|
+
ids = []
|
|
56
|
+
declaration = repository.resolve(element.name,
|
|
57
|
+
element.namespace_uri)
|
|
58
|
+
if declaration
|
|
59
|
+
collect_element_ids(element, declaration, ids, repository)
|
|
60
|
+
collect_attribute_ids(element, declaration, ids, repository)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
element.children.each do |child|
|
|
64
|
+
ids.concat(collect_ids(child, repository))
|
|
65
|
+
end
|
|
66
|
+
ids.compact
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @return [void]
|
|
70
|
+
def collect_element_ids(element, declaration, ids, repository)
|
|
71
|
+
return unless builtin_typed?(declaration, repository, "ID")
|
|
72
|
+
|
|
73
|
+
# ID/IDREF(S) collapse whitespace (token derivation) — the
|
|
74
|
+
# value space is the collapsed form, never the raw lexical
|
|
75
|
+
# (dtZ107447: " John " both sides).
|
|
76
|
+
ids.concat(element.text_content.to_s.split)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# @return [void]
|
|
80
|
+
def collect_attribute_ids(element, declaration, ids, repository)
|
|
81
|
+
typed_attributes(declaration, repository, "ID").each do |attr|
|
|
82
|
+
instance = element.attributes.find do |candidate|
|
|
83
|
+
candidate.name == attr.name
|
|
84
|
+
end
|
|
85
|
+
ids.concat(instance.value.to_s.split) if instance
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Phase 2: every IDREF(S) value the document carries or its
|
|
90
|
+
# declarations SUPPLY, each token matched against the IDs.
|
|
91
|
+
#
|
|
92
|
+
# @return [void]
|
|
93
|
+
def check_references(element, ids, collector, repository)
|
|
94
|
+
declaration = repository.resolve(element.name,
|
|
95
|
+
element.namespace_uri)
|
|
96
|
+
if declaration
|
|
97
|
+
check_element_reference(element, declaration, ids, collector,
|
|
98
|
+
repository)
|
|
99
|
+
check_attribute_references(element, declaration, ids,
|
|
100
|
+
collector, repository)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
element.children.each do |child|
|
|
104
|
+
check_references(child, ids, collector, repository)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# @return [void]
|
|
109
|
+
def check_element_reference(element, declaration, ids, collector,
|
|
110
|
+
repository)
|
|
111
|
+
return unless
|
|
112
|
+
builtin_typed?(declaration, repository, "IDREF") ||
|
|
113
|
+
builtin_typed?(declaration, repository, "IDREFS")
|
|
114
|
+
|
|
115
|
+
reference_values(element.text_content.to_s).each do |value|
|
|
116
|
+
next if ids.include?(value)
|
|
117
|
+
|
|
118
|
+
report_unresolved(value, element, collector, "element")
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Instance values, then the declaration's fixed/default supply
|
|
123
|
+
# for ABSENT attributes — a defaulted IDREFS still references
|
|
124
|
+
# (idZ012).
|
|
125
|
+
#
|
|
126
|
+
# @return [void]
|
|
127
|
+
def check_attribute_references(element, declaration, ids, collector,
|
|
128
|
+
repository)
|
|
129
|
+
typed_attributes(declaration, repository, "IDREF").each do |attr|
|
|
130
|
+
report_tokens(element, attr, ids, collector,
|
|
131
|
+
instance_value(element, attr))
|
|
132
|
+
end
|
|
133
|
+
typed_attributes(declaration, repository, "IDREFS").each do |attr|
|
|
134
|
+
report_tokens(element, attr, ids, collector,
|
|
135
|
+
instance_value(element, attr))
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# @return [String, nil]
|
|
140
|
+
def instance_value(element, attr)
|
|
141
|
+
instance = element.attributes.find do |candidate|
|
|
142
|
+
candidate.name == attr.name
|
|
143
|
+
end
|
|
144
|
+
instance&.value || attr.fixed || attr.default
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# @return [void]
|
|
148
|
+
def report_tokens(element, attr, ids, collector, supplied)
|
|
149
|
+
reference_values(supplied).each do |value|
|
|
150
|
+
next if ids.include?(value)
|
|
151
|
+
|
|
152
|
+
report_unresolved(value, element, collector,
|
|
153
|
+
"attribute '#{attr.name}'")
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# IDREF is a single value; IDREFS tokenizes on whitespace.
|
|
158
|
+
#
|
|
159
|
+
# @return [Array<String>]
|
|
160
|
+
def reference_values(supplied)
|
|
161
|
+
supplied.to_s.strip.empty? ? [] : supplied.to_s.split
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# @return [void]
|
|
165
|
+
def report_unresolved(value, xml_element, collector, subject)
|
|
166
|
+
report_error(
|
|
167
|
+
collector,
|
|
168
|
+
code: "idref_violation",
|
|
169
|
+
message: "#{subject} has IDREF value '#{value}' that " \
|
|
170
|
+
"does not match any ID in the document",
|
|
171
|
+
location: xml_element.xpath,
|
|
172
|
+
context: { value: value },
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Whether the declaration's type is the named builtin — a
|
|
177
|
+
# direct reference or an inline restriction of it.
|
|
178
|
+
#
|
|
179
|
+
# @return [Boolean]
|
|
180
|
+
def builtin_typed?(declaration, _repository, name)
|
|
181
|
+
builtin_reference?(declaration.type.to_s, name) ||
|
|
182
|
+
builtin_reference?(
|
|
183
|
+
declaration.simple_type&.restriction&.base.to_s, name
|
|
184
|
+
)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# @return [Boolean]
|
|
188
|
+
def builtin_reference?(reference, name)
|
|
189
|
+
parts = reference.split(":")
|
|
190
|
+
parts.size == 2 && %w[xs xsd].include?(parts.first) &&
|
|
191
|
+
parts.last == name
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# The declaration's own attribute particles typed the builtin:
|
|
195
|
+
# direct attributes, refs resolved to their declarations, and
|
|
196
|
+
# attributeGroup members.
|
|
197
|
+
#
|
|
198
|
+
# @return [Array<Lutaml::Xml::Schema::Xsd::Attribute>]
|
|
199
|
+
def typed_attributes(schema_element, repository, name)
|
|
200
|
+
type = schema_element.complex_type ||
|
|
201
|
+
repository.resolve_type(schema_element)
|
|
202
|
+
return [] unless type.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
|
|
203
|
+
|
|
204
|
+
particles = Array(type.attribute)
|
|
205
|
+
Array(type.attribute_group).each do |group|
|
|
206
|
+
declaration = repository.resolve_attribute_group(
|
|
207
|
+
(group.ref || group.name).to_s.split(":").last,
|
|
208
|
+
)
|
|
209
|
+
particles.concat(Array(declaration&.attribute))
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
particles.filter_map do |particle|
|
|
213
|
+
resolved = particle
|
|
214
|
+
unless particle.ref.to_s.empty?
|
|
215
|
+
resolved = repository.resolve_attribute(
|
|
216
|
+
particle.ref.split(":").last, nil
|
|
217
|
+
)
|
|
218
|
+
end
|
|
219
|
+
next nil unless resolved && builtin_typed?(resolved, repository,
|
|
220
|
+
name)
|
|
221
|
+
|
|
222
|
+
resolved
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
data/lib/lutaml/xsd/version.rb
CHANGED
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.
|
|
4
|
+
version: 1.2.98
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -578,6 +578,7 @@ files:
|
|
|
578
578
|
- lib/lutaml/xsd/validation/rules/element_structure_rule.rb
|
|
579
579
|
- lib/lutaml/xsd/validation/rules/id_uniqueness_rule.rb
|
|
580
580
|
- lib/lutaml/xsd/validation/rules/identity_constraints_rule.rb
|
|
581
|
+
- lib/lutaml/xsd/validation/rules/idref_resolution_rule.rb
|
|
581
582
|
- lib/lutaml/xsd/validation/rules/occurrence_validation_rule.rb
|
|
582
583
|
- lib/lutaml/xsd/validation/rules/type_validation_rule.rb
|
|
583
584
|
- lib/lutaml/xsd/validation/schema_definition_resolver.rb
|