moxml 0.5.118 → 0.5.119
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/README.adoc +1 -1
- data/lib/moxml/adapter/base.rb +14 -0
- data/lib/moxml/adapter/leptris.rb +33 -0
- data/lib/moxml/context.rb +12 -0
- data/lib/moxml/version.rb +1 -1
- data/lib/moxml/xsd.rb +66 -0
- data/lib/moxml.rb +1 -0
- data/spec/moxml/xsd_spec.rb +66 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7a30730e871854c7b88fc3b6a3498b4f4d5504ac47caa2aabcc530f2bf0eec96
|
|
4
|
+
data.tar.gz: 8d4f301d7d100cab15cc55b4f0e3db36bc5e50916775adfd34f64b816546d466
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b61a839f7399e0b9e9236b1d921cfc161714b114d73da1b737a80c98795d8c88b96f8e85e71c3a71f58a090578b2ba6ffa4ec57cb9a6309cb53296bb000b277
|
|
7
|
+
data.tar.gz: b42fa624031b28da813039d441024be7766f8322fc54f247075b0c205cb79ec57052ababc789ab90f1c3b91b04a0ced4de85760af3178c1675aedd390fdd8046
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
|
@@ -119,7 +119,7 @@ carries the plan-ABI surface, the 1.9.290 XSLT-params and
|
|
|
119
119
|
bulk-append faces, and the 1.9.292 engine deep-copy root install).
|
|
120
120
|
|===
|
|
121
121
|
|
|
122
|
-
NOTE: moxml's dev Gemfile pins `leptris ~> 1.9.
|
|
122
|
+
NOTE: moxml's dev Gemfile pins `leptris ~> 1.9.321` (the tested pair; the gemspec itself has zero runtime dependencies). Consumers of the leptris adapter should run leptris 1.9.320+ — earlier engines carry silent wrong-answer plan-path defects (moxml#344); moxml gates degrade to the always-correct slower paths below it.
|
|
123
123
|
`ox ~> 2.14`, `libxml-ruby >= 5.0`, and the vendored oga fork — the CI
|
|
124
124
|
matrix tests exactly those floors.
|
|
125
125
|
|
data/lib/moxml/adapter/base.rb
CHANGED
|
@@ -258,6 +258,20 @@ module Moxml
|
|
|
258
258
|
raise Moxml::NotImplementedError, XSLT_UNSUPPORTED_MESSAGE
|
|
259
259
|
end
|
|
260
260
|
|
|
261
|
+
# XSD validation (moxml XSD contract): engines without a
|
|
262
|
+
# validator raise; leptris gates on >= 1.9.321.0.
|
|
263
|
+
XSD_SUPPORTED = false
|
|
264
|
+
|
|
265
|
+
def xsd_compile(_schema_source)
|
|
266
|
+
raise Moxml::NotImplementedError,
|
|
267
|
+
"XSD validation requires an adapter with an XSD engine"
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def xsd_validate(_xsd_handle, _native_document)
|
|
271
|
+
raise Moxml::NotImplementedError,
|
|
272
|
+
"XSD validation requires an adapter with an XSD engine"
|
|
273
|
+
end
|
|
274
|
+
|
|
261
275
|
# Apply a compiled stylesheet; returns the engine's result
|
|
262
276
|
# document, or nil when the output method cannot produce one
|
|
263
277
|
# (text). @params is the flat quoted name/value list.
|
|
@@ -165,6 +165,18 @@ module Moxml
|
|
|
165
165
|
# binding 1.9.313): the DSL accumulates markup in a plain
|
|
166
166
|
# String and ONE native crossing (parse + attach) flushes the
|
|
167
167
|
# whole subtree. See Adapter::Base#builder_face.
|
|
168
|
+
# XSD validation (leptris-ruby tier-1, #1075): the binding's
|
|
169
|
+
# Leptris::XML::XSD faces — >= 1.9.321.0 carries instance
|
|
170
|
+
# validation with accumulated errors (slices 3-4). Face probe
|
|
171
|
+
# pairs the gate (misrelease races — NATIVE_PLAN_STRUCTS
|
|
172
|
+
# lesson).
|
|
173
|
+
NATIVE_XSD =
|
|
174
|
+
Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.321.0") &&
|
|
175
|
+
defined?(::Leptris::XML::XSD) &&
|
|
176
|
+
::Leptris::XML::FFI.respond_to?(:leptris_xsd_validate)
|
|
177
|
+
|
|
178
|
+
XSD_SUPPORTED = NATIVE_XSD
|
|
179
|
+
|
|
168
180
|
NATIVE_BUILDER =
|
|
169
181
|
defined?(::Leptris::XML::Builder) &&
|
|
170
182
|
defined?(::Leptris::XML::Document) &&
|
|
@@ -218,6 +230,27 @@ module Moxml
|
|
|
218
230
|
# (and on installs without the native layer — the constant
|
|
219
231
|
# check short-circuits), a Node.wrap over the shared C
|
|
220
232
|
# pointer for NativeNodes.
|
|
233
|
+
def xsd_compile(schema_source)
|
|
234
|
+
unless XSD_SUPPORTED
|
|
235
|
+
raise Moxml::NotImplementedError,
|
|
236
|
+
"XSD validation requires the leptris 1.9.321+ engine"
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
::Leptris::XML::XSD.compile(schema_source)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def xsd_validate(xsd_handle, native_document)
|
|
243
|
+
# +xsd_handle+ is the binding's Leptris::XML::XSD::Schema;
|
|
244
|
+
# validate_errors takes the binding document and returns
|
|
245
|
+
# the engine's accumulated messages ([] = valid).
|
|
246
|
+
doc = if native_document.is_a?(::Leptris::XML::Document)
|
|
247
|
+
native_document
|
|
248
|
+
else
|
|
249
|
+
to_binding(native_document)
|
|
250
|
+
end
|
|
251
|
+
xsd_handle.validate_errors(doc)
|
|
252
|
+
end
|
|
253
|
+
|
|
221
254
|
def builder_face(native_document)
|
|
222
255
|
return nil unless NATIVE_BUILDER && NATIVE_READ_LAYER
|
|
223
256
|
|
data/lib/moxml/context.rb
CHANGED
|
@@ -144,6 +144,18 @@ module Moxml
|
|
|
144
144
|
# @return [Moxml::XSLT::Stylesheet]
|
|
145
145
|
# @raise [Moxml::NotImplementedError] on adapters without an engine
|
|
146
146
|
# @raise [Moxml::XsltError] on a malformed stylesheet
|
|
147
|
+
# Compile an XSD schema for validation (moxml XSD contract).
|
|
148
|
+
# Returns a Moxml::XSD::Schema; #validate/#valid? take a node or
|
|
149
|
+
# raw XML string. Adapters without an engine raise
|
|
150
|
+
# Moxml::NotImplementedError; Moxml::XSD.supported?(self)
|
|
151
|
+
# answers without raising.
|
|
152
|
+
#
|
|
153
|
+
# @raise [Moxml::NotImplementedError] on adapters without a validator
|
|
154
|
+
def xsd(schema_source)
|
|
155
|
+
handle = config.adapter.xsd_compile(schema_source.to_s)
|
|
156
|
+
Moxml::XSD::Schema.new(handle, self)
|
|
157
|
+
end
|
|
158
|
+
|
|
147
159
|
def xslt(stylesheet)
|
|
148
160
|
source = case stylesheet
|
|
149
161
|
when Moxml::Document then stylesheet.to_xml
|
data/lib/moxml/version.rb
CHANGED
data/lib/moxml/xsd.rb
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Moxml
|
|
4
|
+
# XSD validation. Implementation-agnostic over engines that ship
|
|
5
|
+
# an XSD validator (currently leptris, tier-1: named+typed
|
|
6
|
+
# top-level elements, one-level content-model descent, lexical
|
|
7
|
+
# builtin/simpleType checks — see docs/c14n for the sibling
|
|
8
|
+
# pattern).
|
|
9
|
+
#
|
|
10
|
+
# ctx = Moxml.new(:leptris)
|
|
11
|
+
# schema = ctx.xsd(<<~XSD)
|
|
12
|
+
# <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
13
|
+
# <xs:element name="note" type="t_note"/>
|
|
14
|
+
# <xs:complexType name="t_note">
|
|
15
|
+
# <xs:sequence>
|
|
16
|
+
# <xs:element name="to" type="xs:string"/>
|
|
17
|
+
# </xs:sequence>
|
|
18
|
+
# </xs:complexType>
|
|
19
|
+
# </xs:schema>
|
|
20
|
+
# XSD
|
|
21
|
+
# schema.valid?(doc) # => true/false
|
|
22
|
+
# schema.validate(doc) # => [] or ["1:0: ...", ...]
|
|
23
|
+
#
|
|
24
|
+
# Adapters without an engine raise Moxml::NotImplementedError at
|
|
25
|
+
# compile; Moxml::XSD.supported?(context) answers without
|
|
26
|
+
# raising. The tier-1 scope is the engine's: documents outside it
|
|
27
|
+
# validate laxly (see the binding's xsd_validate_spec).
|
|
28
|
+
module XSD
|
|
29
|
+
SUPPORTED_ADAPTERS = %i[leptris].freeze
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
# Whether the context's adapter ships an XSD validator.
|
|
33
|
+
# Answers without raising; compile raises
|
|
34
|
+
# Moxml::NotImplementedError regardless (the capability probe
|
|
35
|
+
# is advisory).
|
|
36
|
+
def supported?(context)
|
|
37
|
+
adapter = context.config.adapter
|
|
38
|
+
adapter.const_defined?(:XSD_SUPPORTED) &&
|
|
39
|
+
adapter.const_get(:XSD_SUPPORTED)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# A compiled schema (adapter-owned handle). Validation results
|
|
44
|
+
# are the engine's accumulated messages; [] means valid.
|
|
45
|
+
class Schema
|
|
46
|
+
def initialize(handle, context)
|
|
47
|
+
@handle = handle
|
|
48
|
+
@context = context
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Validate a node or raw XML string. Returns [] when valid.
|
|
52
|
+
def validate(node_or_xml)
|
|
53
|
+
doc = case node_or_xml
|
|
54
|
+
when Moxml::Document then node_or_xml
|
|
55
|
+
when Moxml::Node then node_or_xml.document
|
|
56
|
+
else @context.parse(node_or_xml.to_s)
|
|
57
|
+
end
|
|
58
|
+
@context.config.adapter.xsd_validate(@handle, doc.native)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def valid?(node_or_xml)
|
|
62
|
+
validate(node_or_xml).empty?
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/moxml.rb
CHANGED
|
@@ -101,6 +101,7 @@ module Moxml
|
|
|
101
101
|
autoload :Signature, "moxml/signature"
|
|
102
102
|
autoload :C14n, "moxml/c14n"
|
|
103
103
|
autoload :XSLT, "moxml/xslt"
|
|
104
|
+
autoload :XSD, "moxml/xsd"
|
|
104
105
|
|
|
105
106
|
# Error hierarchy — each subclass autoloads from the same file
|
|
106
107
|
autoload :Error, "moxml/error"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# Moxml::XSD contract (leptris tier-1 faces): compile + validate
|
|
6
|
+
# with accumulated errors; unsupported adapters raise
|
|
7
|
+
# NotImplementedError at compile.
|
|
8
|
+
RSpec.describe Moxml::XSD do
|
|
9
|
+
let(:ctx) { Moxml.new(:leptris) }
|
|
10
|
+
let(:schema_text) do
|
|
11
|
+
<<~XSD
|
|
12
|
+
<?xml version="1.0"?>
|
|
13
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
14
|
+
<xs:element name="note" type="t_note"/>
|
|
15
|
+
<xs:complexType name="t_note">
|
|
16
|
+
<xs:sequence>
|
|
17
|
+
<xs:element name="to" type="xs:string"/>
|
|
18
|
+
</xs:sequence>
|
|
19
|
+
</xs:complexType>
|
|
20
|
+
</xs:schema>
|
|
21
|
+
XSD
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "reports supported? on the leptris adapter" do
|
|
25
|
+
skip "leptris adapter unavailable" unless
|
|
26
|
+
Moxml::Adapter::Leptris::XSD_SUPPORTED
|
|
27
|
+
|
|
28
|
+
expect(described_class.supported?(ctx)).to be(true)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "when the adapter ships a validator" do
|
|
32
|
+
before do
|
|
33
|
+
skip "leptris 1.9.321+ engine required" unless
|
|
34
|
+
Moxml::Adapter::Leptris::XSD_SUPPORTED
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "compiles and validates a good document" do
|
|
38
|
+
schema = ctx.xsd(schema_text)
|
|
39
|
+
doc = ctx.parse("<note><to>You</to></note>")
|
|
40
|
+
expect(schema.valid?(doc)).to be(true)
|
|
41
|
+
expect(schema.validate(doc)).to eq([])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "returns accumulated messages for an invalid document" do
|
|
45
|
+
schema = ctx.xsd(schema_text)
|
|
46
|
+
errors = schema.validate("<note><wrong/></note>")
|
|
47
|
+
expect(errors).not_to be_empty
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "validates raw XML strings and nodes" do
|
|
51
|
+
schema = ctx.xsd(schema_text)
|
|
52
|
+
doc = ctx.parse("<note><to>x</to></note>")
|
|
53
|
+
expect(schema.valid?(doc.root)).to be(true)
|
|
54
|
+
expect(schema.valid?("<note><to>x</to></note>")).to be(true)
|
|
55
|
+
expect(schema.valid?("<note><wrong/></note>")).to be(false)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "derives XSD_SUPPORTED from the engine face gate" do
|
|
59
|
+
# The capability flag must not outrun the engine faces: a
|
|
60
|
+
# misreleased lockstep (NATIVE_PLAN_STRUCTS lesson) would arm
|
|
61
|
+
# compile against missing functions.
|
|
62
|
+
expect(Moxml::Adapter::Leptris::XSD_SUPPORTED)
|
|
63
|
+
.to eq(Moxml::Adapter::Leptris::NATIVE_XSD)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.119
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -297,6 +297,7 @@ files:
|
|
|
297
297
|
- lib/moxml/xpath/parser.rb
|
|
298
298
|
- lib/moxml/xpath/ruby/generator.rb
|
|
299
299
|
- lib/moxml/xpath/ruby/node.rb
|
|
300
|
+
- lib/moxml/xsd.rb
|
|
300
301
|
- lib/moxml/xslt.rb
|
|
301
302
|
- lib/moxml/xslt/stylesheet.rb
|
|
302
303
|
- moxml.gemspec
|
|
@@ -569,6 +570,7 @@ files:
|
|
|
569
570
|
- spec/moxml/xpath/union_spec.rb
|
|
570
571
|
- spec/moxml/xpath_capabilities_spec.rb
|
|
571
572
|
- spec/moxml/xpath_spec.rb
|
|
573
|
+
- spec/moxml/xsd_spec.rb
|
|
572
574
|
- spec/moxml/xslt/stylesheet_spec.rb
|
|
573
575
|
- spec/performance/README.md
|
|
574
576
|
- spec/performance/benchmark_spec.rb
|