moxml 0.5.169 → 0.5.170

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: c6d162a122e231644310d60b9f27eef7f3fa89728a6c135a9eb855d56952af5d
4
- data.tar.gz: 7c3c92e7ffe80f35484e364d75808d1a74f4c62db7c1e2222b0d1d2921d3ccac
3
+ metadata.gz: 68f6b7acd8107269dc0e15246d3990ef57d3afaa0516896c43fa2db3acfc4cc5
4
+ data.tar.gz: b6511730c2af6f71b66b1a07b118260fc76c6069bd000be29539beb7462522b5
5
5
  SHA512:
6
- metadata.gz: 4872ca2eb4456ee02a511196840379610f6c66b590d64ba1a4715b6107c33a912056bd6fe48055d1270c274e9aec62193f88778180f57ebe32da3f27961f871c
7
- data.tar.gz: 4811ea416c2ebd77ff2cbedf4f640a755424e5ae67d3590c63220fd182eff8ad2fb0c58335ea82f90bb8b9c5bca9f408cb4989256a9c74bb6af5b568ecfc457b
6
+ metadata.gz: b3c3f675bc7ecc526414d7cf045e33dbbcd14ff4b52794552a7ccd4d69b6efab0e3bf14cf5d56e05e3b48e7852795a6a9181ac15c98504233dac324c0c54a6ec
7
+ data.tar.gz: 47fdcc6d4e46766f75bf4927b89ae95931d8920e0fc5f8213a48167b2f5b19ded9f1807bbf13c2351e8735e71e3210f7829f913a7bbb2a82781ca88a68405729
@@ -45,6 +45,7 @@ Generated by `bundle exec rake docs:coverage` from the coverage matrix and the d
45
45
  | validation engine metadata | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
46
46
  | validation regex dismissal | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
47
47
  | validation builtin lexical table | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
48
+ | validation schema sets | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
48
49
  | validation substitution dismissal | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
49
50
  | loud capability contracts | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
50
51
  |===
@@ -255,7 +255,7 @@ semantics.
255
255
 
256
256
  === Validation
257
257
 
258
- Pins:: `spec/moxml/xsd_builtin_lexical_spec.rb`, `spec/moxml/xsd_engine_meta_spec.rb`, `spec/moxml/xsd_regex_spec.rb`, `spec/moxml/xsd_spec.rb`, `spec/moxml/xsd_substitution_spec.rb`, `spec/moxml/xsd_underdetection_spec.rb`, `spec/moxml/xsd_version_spec.rb`
258
+ Pins:: `spec/moxml/xsd_builtin_lexical_spec.rb`, `spec/moxml/xsd_engine_meta_spec.rb`, `spec/moxml/xsd_regex_spec.rb`, `spec/moxml/xsd_set_spec.rb`, `spec/moxml/xsd_spec.rb`, `spec/moxml/xsd_substitution_spec.rb`, `spec/moxml/xsd_underdetection_spec.rb`, `spec/moxml/xsd_version_spec.rb`
259
259
 
260
260
  XSD validation through engines that ship a validator (libxml2;
261
261
  leptris tier-1: recognized roots, one-level content descent, lexical
@@ -265,7 +265,13 @@ spaces (collapse for the token family, the unbounded integer family
265
265
  with bignum bounds, calendar and duration grammars, binary, QName
266
266
  with the reserved `xmlns` prefix) from the facade's own table on
267
267
  every adapter — an engine table converges to it, never the reverse;
268
- an unknown name raises `ArgumentError`. `validate` returns
268
+ an unknown name raises `ArgumentError`. Schema-set compilation
269
+ compiles a LIST of documents into one schema (`Context#xsd_set`):
270
+ imports resolve across the whole set, so components declared in
271
+ importing documents — substitution-group members, derived types —
272
+ are visible to the head's content models; the single-document
273
+ faces cannot see them. Adapters without a set-capable engine raise
274
+ `Moxml::NotImplementedError`. `validate` returns
269
275
  accumulated `ValidationError` entries —
270
276
  message always; line/column/path where the engine reports them, nil
271
277
  where it does not; `[]` means valid. Documents outside the engine's
@@ -373,6 +373,12 @@ module Moxml
373
373
  "XSD validation requires an adapter with an XSD engine"
374
374
  end
375
375
 
376
+ def xsd_compile_set(_paths)
377
+ raise Moxml::NotImplementedError,
378
+ "Schema-set compilation requires an XSD engine with the " \
379
+ "compile_set face"
380
+ end
381
+
376
382
  def xsd_declarations(_xsd_handle); end
377
383
 
378
384
  def xsd_compile_error(_xsd_handle); end
@@ -372,6 +372,23 @@ module Moxml
372
372
  ::Leptris::XML::XSD.compile_file(path)
373
373
  end
374
374
 
375
+ # Schema-set compilation (leptris 1.9.387, moxml#483 item 4):
376
+ # every document compiles into one schema, so imports resolve
377
+ # across the set and substitution-group members declared in
378
+ # importing documents are visible to the head's content
379
+ # models. Path-sourced only — the engine face reads files.
380
+ def xsd_compile_set(paths)
381
+ unless XSD_SUPPORTED &&
382
+ defined?(::Leptris::XML::XSD::Schema) &&
383
+ ::Leptris::XML::XSD::Schema.respond_to?(:compile_set)
384
+ raise Moxml::NotImplementedError,
385
+ "Schema-set compilation requires the leptris 1.9.387+ " \
386
+ "engine (the compile_set face)"
387
+ end
388
+
389
+ ::Leptris::XML::XSD.compile_set(paths)
390
+ end
391
+
375
392
  def relaxng_compile(schema_source)
376
393
  unless RELAXNG_SUPPORTED
377
394
  raise Moxml::NotImplementedError,
data/lib/moxml/context.rb CHANGED
@@ -222,6 +222,24 @@ module Moxml
222
222
  Moxml::XSD::Schema.new(handle, self, source)
223
223
  end
224
224
 
225
+ # Compile a SET of schema documents (paths) into one schema:
226
+ # imports resolve across the whole set, so components declared
227
+ # in importing documents (substitution-group members, derived
228
+ # types) are visible to the head's content models — the
229
+ # single-document faces cannot see them (#483 item 4). The
230
+ # Schema's #version / SchemaRules index read the HEAD document
231
+ # (the first path); engine-set semantics cover the rest.
232
+ # Adapters without a set-capable engine raise
233
+ # Moxml::NotImplementedError.
234
+ def xsd_set(*paths)
235
+ paths = paths.first if paths.size == 1 && paths.first.is_a?(Array)
236
+ raise ArgumentError, "schema set needs at least one path" if paths.empty?
237
+
238
+ handle = config.adapter.xsd_compile_set(paths.map(&:to_s))
239
+ source = File.read(paths.first.to_s)
240
+ Moxml::XSD::Schema.new(handle, self, source)
241
+ end
242
+
225
243
  # Compile a RELAX NG schema from source or from a file path (the
226
244
  # engine resolves relative includes against the file's directory).
227
245
  # Adapters without an RNG engine raise Moxml::NotImplementedError.
data/lib/moxml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.169"
4
+ VERSION = "0.5.170"
5
5
  end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Processing model §Validation (normative): pinned here.
4
+
5
+ require "spec_helper"
6
+
7
+ RSpec.describe "Schema-set compilation" do
8
+ let(:ctx) { Moxml.new(:leptris) }
9
+
10
+ # leptris#1881 / moxml#483 item 4: a head document cannot see
11
+ # substitution-group members declared in schemas that import it;
12
+ # the set face merges every document into one compilation.
13
+ def write_set(dir)
14
+ File.write(File.join(dir, "f.xsd"), <<~XSD)
15
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
16
+ xmlns="urn:F" xmlns:f="urn:F" targetNamespace="urn:F"
17
+ elementFormDefault="qualified">
18
+ <xs:complexType name="foo">
19
+ <xs:sequence><xs:any/></xs:sequence>
20
+ </xs:complexType>
21
+ <xs:element name="foo" type="foo"/>
22
+ <xs:element name="bar">
23
+ <xs:complexType>
24
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
25
+ <xs:element ref="f:foo"/>
26
+ <xs:element ref="f:bar"/>
27
+ </xs:choice>
28
+ </xs:complexType>
29
+ </xs:element>
30
+ </xs:schema>
31
+ XSD
32
+ File.write(File.join(dir, "g.xsd"), <<~XSD)
33
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
34
+ xmlns:g="urn:G" xmlns:f="urn:F" targetNamespace="urn:G"
35
+ elementFormDefault="qualified">
36
+ <xs:import namespace="urn:F" schemaLocation="f.xsd"/>
37
+ <xs:element name="foo1" substitutionGroup="f:foo">
38
+ <xs:complexType>
39
+ <xs:complexContent>
40
+ <xs:extension base="f:foo">
41
+ <xs:attribute name="x" type="xs:int"/>
42
+ </xs:extension>
43
+ </xs:complexContent>
44
+ </xs:complexType>
45
+ </xs:element>
46
+ </xs:schema>
47
+ XSD
48
+ [File.join(dir, "f.xsd"), File.join(dir, "g.xsd")]
49
+ end
50
+
51
+ # The binding carries the face from 1.9.386.0 (engine 1.9.387);
52
+ # published bindings below it loud-fail by contract, so the live
53
+ # examples skip until the ride lands.
54
+ def set_capable?
55
+ defined?(Leptris::XML::XSD::Schema) &&
56
+ Leptris::XML::XSD::Schema.respond_to?(:compile_set)
57
+ end
58
+
59
+ it "admits substitution members declared in importing documents" do
60
+ skip "requires the leptris compile_set face (binding 1.9.386.0+)" unless
61
+ set_capable?
62
+
63
+ Dir.mktmpdir do |dir|
64
+ paths = write_set(dir)
65
+ schema = ctx.xsd_set(*paths)
66
+ doc = ctx.parse(
67
+ '<f:foo xmlns:f="urn:F" xmlns:g="urn:G">' \
68
+ '<f:bar><g:foo1 x="1"><f:bar/></g:foo1></f:bar></f:foo>',
69
+ )
70
+ expect(schema.validate(doc)).to be_empty
71
+ end
72
+ end
73
+
74
+ it "accepts the paths as an array or as arguments" do
75
+ skip "requires the leptris compile_set face (binding 1.9.386.0+)" unless
76
+ set_capable?
77
+
78
+ Dir.mktmpdir do |dir|
79
+ paths = write_set(dir)
80
+ expect(ctx.xsd_set(paths)).to be_a(Moxml::XSD::Schema)
81
+ expect(ctx.xsd_set(*paths)).to be_a(Moxml::XSD::Schema)
82
+ end
83
+ end
84
+
85
+ it "raises on an empty set" do
86
+ expect { ctx.xsd_set }.to raise_error(ArgumentError)
87
+ end
88
+
89
+ it "raises the named error on adapters without a set-capable engine" do
90
+ nk = Moxml.new(:nokogiri)
91
+ Dir.mktmpdir do |dir|
92
+ paths = write_set(dir)
93
+ expect { nk.xsd_set(*paths) }
94
+ .to raise_error(Moxml::NotImplementedError, /compile_set face/)
95
+ end
96
+ end
97
+ end
@@ -101,6 +101,10 @@ module ModelCoverage
101
101
  section: "Validation",
102
102
  pin: "spec/moxml/xsd_builtin_lexical_spec.rb",
103
103
  },
104
+ "validation schema sets" => {
105
+ section: "Validation",
106
+ pin: "spec/moxml/xsd_set_spec.rb",
107
+ },
104
108
  "validation substitution dismissal" => {
105
109
  section: "Validation",
106
110
  pin: "spec/moxml/xsd_substitution_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.169
4
+ version: 0.5.170
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-28 00:00:00.000000000 Z
11
+ date: 2026-10-29 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
@@ -638,6 +638,7 @@ files:
638
638
  - spec/moxml/xsd_handle_mismatch_spec.rb
639
639
  - spec/moxml/xsd_regex_spec.rb
640
640
  - spec/moxml/xsd_release_spec.rb
641
+ - spec/moxml/xsd_set_spec.rb
641
642
  - spec/moxml/xsd_spec.rb
642
643
  - spec/moxml/xsd_substitution_spec.rb
643
644
  - spec/moxml/xsd_underdetection_spec.rb