moxml 0.5.165 → 0.5.167
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/Gemfile +1 -1
- data/benchmark/README.md +9 -9
- data/benchmark/scoreboard.json +32 -32
- data/benchmark/scoreboard.rb +11 -0
- data/docs/_pages/divergences.adoc +10 -0
- data/docs/_pages/model-coverage.adoc +2 -0
- data/docs/_pages/performance.adoc +10 -10
- data/docs/_references/processing-model.adoc +16 -4
- data/lib/moxml/adapter/leptris.rb +110 -4
- data/lib/moxml/config.rb +6 -1
- data/lib/moxml/document.rb +17 -0
- data/lib/moxml/node_set.rb +6 -1
- data/lib/moxml/version.rb +1 -1
- data/lib/moxml/xsd/schema_rules.rb +178 -44
- data/lib/moxml/xsd.rb +39 -5
- data/spec/consistency/xpath_idioms_spec.rb +13 -0
- data/spec/moxml/adapter/leptris_crossdoc_replace_spec.rb +37 -0
- data/spec/moxml/adapter/leptris_native_parent_axis_spec.rb +46 -0
- data/spec/moxml/xsd_engine_meta_spec.rb +66 -0
- data/spec/moxml/xsd_substitution_spec.rb +166 -0
- data/spec/support/model_coverage.rb +8 -0
- metadata +6 -2
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# Processing model §Validation (normative): pinned here.
|
|
6
|
+
# #466 class 1: the engine's content-model matcher matches
|
|
7
|
+
# particles by exact name only, so a valid substitution-group
|
|
8
|
+
# member is rejected with "children do not match the content
|
|
9
|
+
# model". The Ruby-side dismissal drops such a finding only when
|
|
10
|
+
# the parent's content model is a pure sequence, the child
|
|
11
|
+
# sequence matches it position-for-position with every particle
|
|
12
|
+
# exactly-once, and a registered member realizes a position —
|
|
13
|
+
# any choice/all, cardinality violation, or unknown name keeps
|
|
14
|
+
# the engine's answer, so the dismissal can only remove false
|
|
15
|
+
# rejections, never create false acceptances.
|
|
16
|
+
RSpec.describe "Moxml::XSD substitution-group dismissal (#466)" do
|
|
17
|
+
%i[nokogiri leptris].each do |adapter_name|
|
|
18
|
+
describe "on #{adapter_name}" do
|
|
19
|
+
let(:ctx) { Moxml.new(adapter_name) }
|
|
20
|
+
|
|
21
|
+
before do
|
|
22
|
+
skip "#{adapter_name} requires an XSD-capable engine" unless
|
|
23
|
+
Moxml::XSD.supported?(ctx)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "member of a referenced head particle" do
|
|
27
|
+
let(:schema) do
|
|
28
|
+
ctx.xsd(<<~XSD)
|
|
29
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
30
|
+
xmlns:x="http://xsdtesting"
|
|
31
|
+
targetNamespace="http://xsdtesting"
|
|
32
|
+
elementFormDefault="qualified">
|
|
33
|
+
<xsd:element name="doc">
|
|
34
|
+
<xsd:complexType>
|
|
35
|
+
<xsd:sequence>
|
|
36
|
+
<xsd:element ref="x:elem1"/>
|
|
37
|
+
</xsd:sequence>
|
|
38
|
+
</xsd:complexType>
|
|
39
|
+
</xsd:element>
|
|
40
|
+
<xsd:element name="elem1" abstract="false"/>
|
|
41
|
+
<xsd:element name="elem2" substitutionGroup="x:elem1"/>
|
|
42
|
+
</xsd:schema>
|
|
43
|
+
XSD
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "accepts the member where the head is declared" do
|
|
47
|
+
doc = ctx.parse(
|
|
48
|
+
'<x:doc xmlns:x="http://xsdtesting"><x:elem2/></x:doc>',
|
|
49
|
+
)
|
|
50
|
+
expect(schema.valid?(doc)).to be(true)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "accepts the head itself" do
|
|
54
|
+
doc = ctx.parse(
|
|
55
|
+
'<x:doc xmlns:x="http://xsdtesting"><x:elem1/></x:doc>',
|
|
56
|
+
)
|
|
57
|
+
expect(schema.valid?(doc)).to be(true)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "rejects a stray non-member child" do
|
|
61
|
+
doc = ctx.parse(
|
|
62
|
+
'<x:doc xmlns:x="http://xsdtesting"><x:unknown/></x:doc>',
|
|
63
|
+
)
|
|
64
|
+
expect(schema.valid?(doc)).to be(false)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe "member inside a nested sequence" do
|
|
69
|
+
let(:schema) do
|
|
70
|
+
ctx.xsd(<<~XSD)
|
|
71
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
72
|
+
xmlns:x="http://xsdtesting"
|
|
73
|
+
targetNamespace="http://xsdtesting"
|
|
74
|
+
elementFormDefault="qualified">
|
|
75
|
+
<xsd:element name="doc">
|
|
76
|
+
<xsd:complexType>
|
|
77
|
+
<xsd:sequence>
|
|
78
|
+
<xsd:element ref="x:mid"/>
|
|
79
|
+
</xsd:sequence>
|
|
80
|
+
</xsd:complexType>
|
|
81
|
+
</xsd:element>
|
|
82
|
+
<xsd:element name="mid">
|
|
83
|
+
<xsd:complexType>
|
|
84
|
+
<xsd:sequence>
|
|
85
|
+
<xsd:element ref="x:elem1"/>
|
|
86
|
+
</xsd:sequence>
|
|
87
|
+
</xsd:complexType>
|
|
88
|
+
</xsd:element>
|
|
89
|
+
<xsd:element name="elem1" abstract="false"/>
|
|
90
|
+
<xsd:element name="elem2" substitutionGroup="x:elem1"/>
|
|
91
|
+
</xsd:schema>
|
|
92
|
+
XSD
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "accepts the member at the inner position" do
|
|
96
|
+
doc = ctx.parse(
|
|
97
|
+
'<x:doc xmlns:x="http://xsdtesting">' \
|
|
98
|
+
"<x:mid><x:elem2/></x:mid></x:doc>",
|
|
99
|
+
)
|
|
100
|
+
expect(schema.valid?(doc)).to be(true)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe "models the dismissal refuses" do
|
|
105
|
+
let(:schema) do
|
|
106
|
+
ctx.xsd(<<~XSD)
|
|
107
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
108
|
+
xmlns:x="http://xsdtesting"
|
|
109
|
+
targetNamespace="http://xsdtesting"
|
|
110
|
+
elementFormDefault="qualified">
|
|
111
|
+
<xsd:element name="doc">
|
|
112
|
+
<xsd:complexType>
|
|
113
|
+
<xsd:choice>
|
|
114
|
+
<xsd:element ref="x:elem1"/>
|
|
115
|
+
<xsd:element name="other"/>
|
|
116
|
+
</xsd:choice>
|
|
117
|
+
</xsd:complexType>
|
|
118
|
+
</xsd:element>
|
|
119
|
+
<xsd:element name="elem1" abstract="false"/>
|
|
120
|
+
<xsd:element name="elem2" substitutionGroup="x:elem1"/>
|
|
121
|
+
</xsd:schema>
|
|
122
|
+
XSD
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "keeps the engine's answer for a two-child choice match" do
|
|
126
|
+
# A choice takes one item; two children cannot be valid
|
|
127
|
+
# even though both names resolve — the flattened particle
|
|
128
|
+
# list is not a validity witness for non-sequences.
|
|
129
|
+
doc = ctx.parse(
|
|
130
|
+
'<x:doc xmlns:x="http://xsdtesting">' \
|
|
131
|
+
"<x:elem2/><x:other/></x:doc>",
|
|
132
|
+
)
|
|
133
|
+
expect(schema.valid?(doc)).to be(false)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
describe "cardinality the dismissal refuses" do
|
|
138
|
+
let(:schema) do
|
|
139
|
+
ctx.xsd(<<~XSD)
|
|
140
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
141
|
+
xmlns:x="http://xsdtesting"
|
|
142
|
+
targetNamespace="http://xsdtesting"
|
|
143
|
+
elementFormDefault="qualified">
|
|
144
|
+
<xsd:element name="doc">
|
|
145
|
+
<xsd:complexType>
|
|
146
|
+
<xsd:sequence>
|
|
147
|
+
<xsd:element ref="x:elem1" minOccurs="2" maxOccurs="2"/>
|
|
148
|
+
</xsd:sequence>
|
|
149
|
+
</xsd:complexType>
|
|
150
|
+
</xsd:element>
|
|
151
|
+
<xsd:element name="elem1" abstract="false"/>
|
|
152
|
+
<xsd:element name="elem2" substitutionGroup="x:elem1"/>
|
|
153
|
+
</xsd:schema>
|
|
154
|
+
XSD
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "keeps the engine's answer below minOccurs" do
|
|
158
|
+
doc = ctx.parse(
|
|
159
|
+
'<x:doc xmlns:x="http://xsdtesting"><x:elem2/></x:doc>',
|
|
160
|
+
)
|
|
161
|
+
expect(schema.valid?(doc)).to be(false)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -89,10 +89,18 @@ module ModelCoverage
|
|
|
89
89
|
section: "Validation",
|
|
90
90
|
pin: "spec/moxml/xsd_version_spec.rb",
|
|
91
91
|
},
|
|
92
|
+
"validation engine metadata" => {
|
|
93
|
+
section: "Validation",
|
|
94
|
+
pin: "spec/moxml/xsd_engine_meta_spec.rb",
|
|
95
|
+
},
|
|
92
96
|
"validation regex dismissal" => {
|
|
93
97
|
section: "Validation",
|
|
94
98
|
pin: "spec/moxml/xsd_regex_spec.rb",
|
|
95
99
|
},
|
|
100
|
+
"validation substitution dismissal" => {
|
|
101
|
+
section: "Validation",
|
|
102
|
+
pin: "spec/moxml/xsd_substitution_spec.rb",
|
|
103
|
+
},
|
|
96
104
|
"loud capability contracts" => {
|
|
97
105
|
section: "Errors and loud degradation",
|
|
98
106
|
pin: "spec/consistency/loud_degradation_spec.rb",
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moxml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.167
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |
|
|
14
14
|
Moxml is a unified XML manipulation library that provides a common API
|
|
@@ -486,11 +486,13 @@ files:
|
|
|
486
486
|
- spec/moxml/adapter/leptris_binding_cap_spec.rb
|
|
487
487
|
- spec/moxml/adapter/leptris_children_columnar_spec.rb
|
|
488
488
|
- spec/moxml/adapter/leptris_contract_reads_spec.rb
|
|
489
|
+
- spec/moxml/adapter/leptris_crossdoc_replace_spec.rb
|
|
489
490
|
- spec/moxml/adapter/leptris_detached_text_spec.rb
|
|
490
491
|
- spec/moxml/adapter/leptris_doc_parts_spec.rb
|
|
491
492
|
- spec/moxml/adapter/leptris_document_children_older_binding_spec.rb
|
|
492
493
|
- spec/moxml/adapter/leptris_document_declaration_spec.rb
|
|
493
494
|
- spec/moxml/adapter/leptris_inbody_comment_spec.rb
|
|
495
|
+
- spec/moxml/adapter/leptris_native_parent_axis_spec.rb
|
|
494
496
|
- spec/moxml/adapter/leptris_parse_lint_spec.rb
|
|
495
497
|
- spec/moxml/adapter/leptris_parse_skips_spec.rb
|
|
496
498
|
- spec/moxml/adapter/leptris_record_driver_spec.rb
|
|
@@ -629,11 +631,13 @@ files:
|
|
|
629
631
|
- spec/moxml/xpath/union_spec.rb
|
|
630
632
|
- spec/moxml/xpath_capabilities_spec.rb
|
|
631
633
|
- spec/moxml/xpath_spec.rb
|
|
634
|
+
- spec/moxml/xsd_engine_meta_spec.rb
|
|
632
635
|
- spec/moxml/xsd_error_contract_spec.rb
|
|
633
636
|
- spec/moxml/xsd_handle_mismatch_spec.rb
|
|
634
637
|
- spec/moxml/xsd_regex_spec.rb
|
|
635
638
|
- spec/moxml/xsd_release_spec.rb
|
|
636
639
|
- spec/moxml/xsd_spec.rb
|
|
640
|
+
- spec/moxml/xsd_substitution_spec.rb
|
|
637
641
|
- spec/moxml/xsd_underdetection_spec.rb
|
|
638
642
|
- spec/moxml/xsd_version_spec.rb
|
|
639
643
|
- spec/moxml/xslt/stylesheet_spec.rb
|