rng 0.1.1 → 0.3.3
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/.github/workflows/docs.yml +63 -0
- data/.github/workflows/release.yml +8 -3
- data/.gitignore +11 -0
- data/.rubocop.yml +11 -6
- data/.rubocop_todo.yml +270 -0
- data/CHANGELOG.md +317 -0
- data/CLAUDE.md +139 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/Gemfile +11 -10
- data/README.adoc +1929 -0
- data/Rakefile +11 -3
- data/docs/Gemfile +8 -0
- data/docs/_config.yml +23 -0
- data/docs/getting-started/index.adoc +75 -0
- data/docs/guides/error-handling.adoc +137 -0
- data/docs/guides/external-references.adoc +128 -0
- data/docs/guides/index.adoc +24 -0
- data/docs/guides/parsing-rnc.adoc +141 -0
- data/docs/guides/parsing-rng-xml.adoc +81 -0
- data/docs/guides/rng-to-rnc.adoc +101 -0
- data/docs/guides/validation.adoc +85 -0
- data/docs/index.adoc +52 -0
- data/docs/reference/api.adoc +126 -0
- data/docs/reference/cli.adoc +182 -0
- data/docs/understanding/architecture.adoc +58 -0
- data/docs/understanding/rng-vs-rnc.adoc +118 -0
- data/exe/rng +5 -0
- data/lib/rng/any_name.rb +28 -0
- data/lib/rng/attribute.rb +61 -5
- data/lib/rng/choice.rb +60 -0
- data/lib/rng/cli.rb +607 -0
- data/lib/rng/data.rb +32 -0
- data/lib/rng/datatype_declaration.rb +26 -0
- data/lib/rng/define.rb +56 -5
- data/lib/rng/div.rb +36 -0
- data/lib/rng/documentation.rb +9 -0
- data/lib/rng/element.rb +66 -18
- data/lib/rng/empty.rb +23 -0
- data/lib/rng/except.rb +62 -0
- data/lib/rng/external_ref.rb +28 -0
- data/lib/rng/external_ref_resolver.rb +582 -0
- data/lib/rng/foreign_attribute.rb +26 -0
- data/lib/rng/foreign_element.rb +33 -0
- data/lib/rng/grammar.rb +38 -0
- data/lib/rng/group.rb +62 -0
- data/lib/rng/include.rb +23 -0
- data/lib/rng/include_processor.rb +461 -0
- data/lib/rng/interleave.rb +58 -0
- data/lib/rng/list.rb +56 -0
- data/lib/rng/mixed.rb +58 -0
- data/lib/rng/name.rb +28 -0
- data/lib/rng/namespace_declaration.rb +47 -0
- data/lib/rng/namespaces.rb +15 -0
- data/lib/rng/not_allowed.rb +23 -0
- data/lib/rng/ns_name.rb +31 -0
- data/lib/rng/one_or_more.rb +58 -0
- data/lib/rng/optional.rb +58 -0
- data/lib/rng/param.rb +30 -0
- data/lib/rng/parent_ref.rb +28 -0
- data/lib/rng/parse_rnc.rb +26 -0
- data/lib/rng/parse_tree_processor.rb +695 -0
- data/lib/rng/pattern.rb +24 -0
- data/lib/rng/ref.rb +28 -0
- data/lib/rng/rnc_builder.rb +927 -0
- data/lib/rng/rnc_parser.rb +672 -115
- data/lib/rng/rnc_to_rng_converter.rb +1408 -0
- data/lib/rng/schema_preamble.rb +73 -0
- data/lib/rng/schema_validator.rb +1622 -0
- data/lib/rng/start.rb +57 -6
- data/lib/rng/test_suite_parser.rb +168 -0
- data/lib/rng/text.rb +29 -0
- data/lib/rng/to_rnc.rb +24 -0
- data/lib/rng/value.rb +28 -0
- data/lib/rng/version.rb +1 -1
- data/lib/rng/zero_or_more.rb +58 -0
- data/lib/rng.rb +80 -5
- data/rng.gemspec +19 -19
- data/scripts/extract_spectest_resources.rb +96 -0
- data/spec/fixtures/compacttest.xml +2511 -0
- data/spec/fixtures/external/circular_a.rng +7 -0
- data/spec/fixtures/external/circular_b.rng +7 -0
- data/spec/fixtures/external/circular_main.rng +7 -0
- data/spec/fixtures/external/external_ref_lib.rng +7 -0
- data/spec/fixtures/external/external_ref_main.rng +7 -0
- data/spec/fixtures/external/include_lib.rng +7 -0
- data/spec/fixtures/external/include_main.rng +3 -0
- data/spec/fixtures/external/nested_chain.rng +6 -0
- data/spec/fixtures/external/nested_leaf.rng +7 -0
- data/spec/fixtures/external/nested_mid.rng +8 -0
- data/spec/fixtures/metanorma/3gpp.rnc +35 -0
- data/spec/fixtures/metanorma/3gpp.rng +105 -0
- data/spec/fixtures/metanorma/basicdoc.rnc +11 -0
- data/spec/fixtures/metanorma/bipm.rnc +148 -0
- data/spec/fixtures/metanorma/bipm.rng +376 -0
- data/spec/fixtures/metanorma/bsi.rnc +104 -0
- data/spec/fixtures/metanorma/bsi.rng +332 -0
- data/spec/fixtures/metanorma/csa.rnc +45 -0
- data/spec/fixtures/metanorma/csa.rng +131 -0
- data/spec/fixtures/metanorma/csd.rnc +43 -0
- data/spec/fixtures/metanorma/csd.rng +132 -0
- data/spec/fixtures/metanorma/gbstandard.rnc +99 -0
- data/spec/fixtures/metanorma/gbstandard.rng +316 -0
- data/spec/fixtures/metanorma/iec.rnc +49 -0
- data/spec/fixtures/metanorma/iec.rng +193 -0
- data/spec/fixtures/metanorma/ietf.rnc +275 -0
- data/spec/fixtures/metanorma/ietf.rng +925 -0
- data/spec/fixtures/metanorma/iho.rnc +58 -0
- data/spec/fixtures/metanorma/iho.rng +179 -0
- data/spec/fixtures/metanorma/isodoc.rnc +873 -0
- data/spec/fixtures/metanorma/isodoc.rng +2704 -0
- data/spec/fixtures/metanorma/isostandard-amd.rnc +43 -0
- data/spec/fixtures/metanorma/isostandard-amd.rng +108 -0
- data/spec/fixtures/metanorma/isostandard.rnc +166 -0
- data/spec/fixtures/metanorma/isostandard.rng +494 -0
- data/spec/fixtures/metanorma/itu.rnc +122 -0
- data/spec/fixtures/metanorma/itu.rng +377 -0
- data/spec/fixtures/metanorma/m3d.rnc +41 -0
- data/spec/fixtures/metanorma/m3d.rng +122 -0
- data/spec/fixtures/metanorma/mpfd.rnc +36 -0
- data/spec/fixtures/metanorma/mpfd.rng +95 -0
- data/spec/fixtures/metanorma/nist.rnc +77 -0
- data/spec/fixtures/metanorma/nist.rng +216 -0
- data/spec/fixtures/metanorma/ogc.rnc +51 -0
- data/spec/fixtures/metanorma/ogc.rng +151 -0
- data/spec/fixtures/metanorma/reqt.rnc +6 -0
- data/spec/fixtures/metanorma/rsd.rnc +36 -0
- data/spec/fixtures/metanorma/rsd.rng +95 -0
- data/spec/fixtures/metanorma/un.rnc +103 -0
- data/spec/fixtures/metanorma/un.rng +367 -0
- data/spec/fixtures/rnc/address_book.rnc +10 -0
- data/spec/fixtures/rnc/base.rnc +4 -0
- data/spec/fixtures/rnc/complex_example.rnc +61 -0
- data/spec/fixtures/rnc/grammar_with_trailing.rnc +8 -0
- data/spec/fixtures/rnc/main_include_trailing.rnc +3 -0
- data/spec/fixtures/rnc/main_with_include.rnc +5 -0
- data/spec/fixtures/rnc/test_augment.rnc +10 -0
- data/spec/fixtures/rnc/test_isodoc_simple.rnc +9 -0
- data/spec/fixtures/rnc/top_level_include.rnc +8 -0
- data/spec/fixtures/rng/address_book.rng +20 -0
- data/spec/fixtures/rng/relaxng.rng +335 -0
- data/spec/fixtures/rng/testSuite.rng +163 -0
- data/spec/fixtures/spectest.xml +6845 -0
- data/spec/fixtures/spectest_external/case_10_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_10_4.7/y +7 -0
- data/spec/fixtures/spectest_external/case_11_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_12_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_13_4.7/x +3 -0
- data/spec/fixtures/spectest_external/case_13_4.7/y +3 -0
- data/spec/fixtures/spectest_external/case_14_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_15_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_16_4.7/x +5 -0
- data/spec/fixtures/spectest_external/case_17_4.7/x +5 -0
- data/spec/fixtures/spectest_external/case_18_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_19_4.7/level1.rng +9 -0
- data/spec/fixtures/spectest_external/case_19_4.7/level2.rng +7 -0
- data/spec/fixtures/spectest_external/case_1_4.5/sub1/x +3 -0
- data/spec/fixtures/spectest_external/case_1_4.5/sub3/x +3 -0
- data/spec/fixtures/spectest_external/case_1_4.5/x +3 -0
- data/spec/fixtures/spectest_external/case_20_4.6/x +3 -0
- data/spec/fixtures/spectest_external/case_2_4.5/x +3 -0
- data/spec/fixtures/spectest_external/case_3_4.6/x +3 -0
- data/spec/fixtures/spectest_external/case_4_4.6/x +3 -0
- data/spec/fixtures/spectest_external/case_5_4.6/x +1 -0
- data/spec/fixtures/spectest_external/case_6_4.6/x +5 -0
- data/spec/fixtures/spectest_external/case_7_4.6/x +1 -0
- data/spec/fixtures/spectest_external/case_7_4.6/y +1 -0
- data/spec/fixtures/spectest_external/case_8_4.7/x +7 -0
- data/spec/fixtures/spectest_external/case_9_4.7/x +7 -0
- data/spec/fixtures/spectest_external/resources.json +149 -0
- data/spec/rng/advanced_rnc_spec.rb +101 -0
- data/spec/rng/compacttest_spec.rb +197 -0
- data/spec/rng/datatype_declaration_spec.rb +28 -0
- data/spec/rng/div_spec.rb +207 -0
- data/spec/rng/external_ref_resolver_spec.rb +122 -0
- data/spec/rng/metanorma_conversion_spec.rb +159 -0
- data/spec/rng/namespace_declaration_spec.rb +60 -0
- data/spec/rng/namespace_support_spec.rb +199 -0
- data/spec/rng/rnc_parser_spec.rb +501 -23
- data/spec/rng/rnc_roundtrip_spec.rb +135 -0
- data/spec/rng/rng_generation_spec.rb +288 -0
- data/spec/rng/roundtrip_spec.rb +342 -0
- data/spec/rng/schema_preamble_spec.rb +145 -0
- data/spec/rng/schema_spec.rb +125 -172
- data/spec/rng/spectest_spec.rb +273 -0
- data/spec/rng_spec.rb +2 -2
- data/spec/spec_helper.rb +7 -9
- metadata +188 -8
- data/lib/rng/builder.rb +0 -158
- data/lib/rng/rng_parser.rb +0 -107
- data/lib/rng/schema.rb +0 -18
- data/spec/rng/rng_parser_spec.rb +0 -102
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Converting RNG to RNC
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 3
|
|
5
|
+
parent: Guides
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Converting Between RNG and RNC
|
|
9
|
+
|
|
10
|
+
The RNG gem supports converting between RNG XML format and RNC compact syntax.
|
|
11
|
+
|
|
12
|
+
== RNG to RNC Conversion
|
|
13
|
+
|
|
14
|
+
Convert a grammar parsed from RNG XML to RNC compact syntax:
|
|
15
|
+
|
|
16
|
+
[source,ruby]
|
|
17
|
+
----
|
|
18
|
+
require 'rng'
|
|
19
|
+
|
|
20
|
+
# Parse RNG XML
|
|
21
|
+
rng_xml = File.read('schema.rng')
|
|
22
|
+
grammar = Rng.parse(rng_xml)
|
|
23
|
+
|
|
24
|
+
# Convert to RNC
|
|
25
|
+
rnc_output = Rng.to_rnc(grammar)
|
|
26
|
+
|
|
27
|
+
puts rnc_output
|
|
28
|
+
----
|
|
29
|
+
|
|
30
|
+
== RNC to RNG Conversion
|
|
31
|
+
|
|
32
|
+
Convert RNC compact syntax to RNG XML:
|
|
33
|
+
|
|
34
|
+
[source,ruby]
|
|
35
|
+
----
|
|
36
|
+
require 'rng'
|
|
37
|
+
|
|
38
|
+
# Parse RNC
|
|
39
|
+
rnc_text = File.read('schema.rnc')
|
|
40
|
+
grammar = Rng.parse_rnc(rnc_text)
|
|
41
|
+
|
|
42
|
+
# Convert to RNG XML
|
|
43
|
+
rng_xml = grammar.to_xml
|
|
44
|
+
|
|
45
|
+
puts rng_xml
|
|
46
|
+
----
|
|
47
|
+
|
|
48
|
+
== Using the CLI
|
|
49
|
+
|
|
50
|
+
The gem includes a CLI for quick conversions:
|
|
51
|
+
|
|
52
|
+
[source,bash]
|
|
53
|
+
----
|
|
54
|
+
# RNG to RNC
|
|
55
|
+
rng convert schema.rng -O rnc -o schema_converted.rnc
|
|
56
|
+
|
|
57
|
+
# RNC to RNG
|
|
58
|
+
rng convert schema.rnc -O rng -o schema_converted.rng
|
|
59
|
+
----
|
|
60
|
+
|
|
61
|
+
== Round-Trip Conversion
|
|
62
|
+
|
|
63
|
+
The gem is designed to produce correct output that can be re-parsed:
|
|
64
|
+
|
|
65
|
+
[source,ruby]
|
|
66
|
+
----
|
|
67
|
+
# Parse RNC
|
|
68
|
+
grammar1 = Rng.parse_rnc(rnc_text)
|
|
69
|
+
|
|
70
|
+
# Convert to RNG and back to RNC
|
|
71
|
+
rng_xml = grammar1.to_xml
|
|
72
|
+
grammar2 = Rng.parse(rng_xml)
|
|
73
|
+
rnc_output = Rng.to_rnc(grammar2)
|
|
74
|
+
|
|
75
|
+
# Both grammars should be equivalent
|
|
76
|
+
----
|
|
77
|
+
|
|
78
|
+
== Limitations
|
|
79
|
+
|
|
80
|
+
1. **Whitespace handling**: Whitespace in RNC is normalized during parsing
|
|
81
|
+
2. **Comments**: RNC comments are not preserved in RNG XML output
|
|
82
|
+
3. **Foreign elements**: Elements from non-RNG namespaces are dropped
|
|
83
|
+
4. **Name classes**: Complex name classes may serialize differently but remain semantically equivalent
|
|
84
|
+
|
|
85
|
+
== Format Selection
|
|
86
|
+
|
|
87
|
+
The conversion direction is inferred from the input format:
|
|
88
|
+
|
|
89
|
+
| Input Format | Output Format |
|
|
90
|
+
|--------------|---------------|
|
|
91
|
+
| `.rnc` file | RNG XML |
|
|
92
|
+
| `.rng` file | RNC |
|
|
93
|
+
| Unknown | RNG XML |
|
|
94
|
+
|
|
95
|
+
Use explicit format flags when the inference is incorrect:
|
|
96
|
+
|
|
97
|
+
[source,bash]
|
|
98
|
+
----
|
|
99
|
+
rng convert input.rnc output.rng -O rng
|
|
100
|
+
rng convert input.rng output.rnc -O rnc
|
|
101
|
+
----
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Schema Validation
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 4
|
|
5
|
+
parent: Guides
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Schema Validation
|
|
9
|
+
|
|
10
|
+
The RNG gem provides structural validation of RNG schemas.
|
|
11
|
+
|
|
12
|
+
== Validating a Schema
|
|
13
|
+
|
|
14
|
+
Validate that an RNG schema is well-formed and follows RELAX NG rules:
|
|
15
|
+
|
|
16
|
+
[source,ruby]
|
|
17
|
+
----
|
|
18
|
+
require 'rng'
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
Rng::SchemaValidator.validate(rng_xml)
|
|
22
|
+
puts "Schema is valid"
|
|
23
|
+
rescue Rng::SchemaValidationError => e
|
|
24
|
+
puts "Schema validation error: #{e.message}"
|
|
25
|
+
end
|
|
26
|
+
----
|
|
27
|
+
|
|
28
|
+
== Validation During Parsing
|
|
29
|
+
|
|
30
|
+
You can also validate during parsing with the `validate:` option:
|
|
31
|
+
|
|
32
|
+
[source,ruby]
|
|
33
|
+
----
|
|
34
|
+
grammar = Rng.parse(rng_xml, validate: true)
|
|
35
|
+
----
|
|
36
|
+
|
|
37
|
+
This is equivalent to:
|
|
38
|
+
|
|
39
|
+
[source,ruby]
|
|
40
|
+
----
|
|
41
|
+
Rng::SchemaValidator.validate(rng_xml)
|
|
42
|
+
grammar = Rng.parse(rng_xml)
|
|
43
|
+
----
|
|
44
|
+
|
|
45
|
+
== Schema Validation Errors
|
|
46
|
+
|
|
47
|
+
When validation fails, a `Rng::SchemaValidationError` is raised:
|
|
48
|
+
|
|
49
|
+
[source,ruby]
|
|
50
|
+
----
|
|
51
|
+
begin
|
|
52
|
+
Rng::SchemaValidator.validate(invalid_rng_xml)
|
|
53
|
+
rescue Rng::SchemaValidationError => e
|
|
54
|
+
puts e.message
|
|
55
|
+
puts e.errors if e.respond_to?(:errors)
|
|
56
|
+
end
|
|
57
|
+
----
|
|
58
|
+
|
|
59
|
+
== What Gets Validated
|
|
60
|
+
|
|
61
|
+
The SchemaValidator checks:
|
|
62
|
+
|
|
63
|
+
1. **Grammar structure**: Start element, proper define elements
|
|
64
|
+
2. **Pattern validity**: Elements properly nested, correct attributes
|
|
65
|
+
3. **Name class validity**: NCName, QName, nsName proper usage
|
|
66
|
+
4. **Datatype Library**: Correct datatype library references
|
|
67
|
+
5. **Reference integrity**: Refs point to defined patterns
|
|
68
|
+
|
|
69
|
+
== Limitations
|
|
70
|
+
|
|
71
|
+
Schema validation does NOT:
|
|
72
|
+
|
|
73
|
+
- Validate XML documents against the schema (use a validator like Jing for that)
|
|
74
|
+
- Check semantic equivalence of patterns
|
|
75
|
+
- Validate external references (those require I/O)
|
|
76
|
+
|
|
77
|
+
== Schema Structure Validation
|
|
78
|
+
|
|
79
|
+
The gem validates the schema structure when parsing with `validate: true`:
|
|
80
|
+
|
|
81
|
+
[source,ruby]
|
|
82
|
+
----
|
|
83
|
+
# This will raise if the schema is invalid
|
|
84
|
+
grammar = Rng.parse(File.read('invalid_schema.rng'), validate: true)
|
|
85
|
+
----
|
data/docs/index.adoc
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: RNG Ruby Gem
|
|
3
|
+
nav_order: 1
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# RNG Ruby Gem
|
|
7
|
+
|
|
8
|
+
A Ruby gem for parsing, manipulating, and converting RELAX NG schemas (both RNG XML and RNC compact syntax).
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Parse RNG XML format
|
|
13
|
+
- Parse RNC compact syntax
|
|
14
|
+
- Convert between RNG and RNC formats
|
|
15
|
+
- Validate RNG schemas
|
|
16
|
+
- Resolve external references (`<include>` and `<externalRef>`)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
gem install rng
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or add to your Gemfile:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
gem 'rng'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
require 'rng'
|
|
34
|
+
|
|
35
|
+
# Parse RNG XML
|
|
36
|
+
rng_xml = File.read('schema.rng')
|
|
37
|
+
grammar = Rng.parse(rng_xml)
|
|
38
|
+
|
|
39
|
+
# Parse RNC compact syntax
|
|
40
|
+
rnc_text = File.read('schema.rnc')
|
|
41
|
+
grammar = Rng.parse_rnc(rnc_text)
|
|
42
|
+
|
|
43
|
+
# Convert RNG to RNC
|
|
44
|
+
rnc_output = Rng.to_rnc(grammar)
|
|
45
|
+
|
|
46
|
+
# Resolve external references
|
|
47
|
+
grammar = Rng.parse(rng_xml, location: '/path/to/schema.rng', resolve_external: true)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Status
|
|
51
|
+
|
|
52
|
+
This gem is under active development. The core parsing functionality is complete and well-tested against the Jing-Trang test suite.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: API Reference
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 5
|
|
5
|
+
has_children: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= API Reference
|
|
9
|
+
|
|
10
|
+
Complete API documentation for the RNG gem.
|
|
11
|
+
|
|
12
|
+
== Main Module: `Rng`
|
|
13
|
+
|
|
14
|
+
=== `Rng.parse`
|
|
15
|
+
|
|
16
|
+
Parse RNG XML format.
|
|
17
|
+
|
|
18
|
+
[source,ruby]
|
|
19
|
+
----
|
|
20
|
+
Rng.parse(rng_xml, location: nil, nested_schema: false, validate: false, resolve_external: false)
|
|
21
|
+
----
|
|
22
|
+
|
|
23
|
+
**Parameters:**
|
|
24
|
+
|
|
25
|
+
- `rng_xml` (String) - The RNG XML content
|
|
26
|
+
- `location` (String, optional) - File location for resolving relative external refs
|
|
27
|
+
- `nested_schema` (Boolean, default: false) - Whether this is a nested schema
|
|
28
|
+
- `validate` (Boolean, default: false) - Whether to validate the schema
|
|
29
|
+
- `resolve_external` (Boolean, default: false) - Whether to resolve external refs
|
|
30
|
+
|
|
31
|
+
**Returns:** `Rng::Grammar`
|
|
32
|
+
|
|
33
|
+
=== `Rng.parse_rnc`
|
|
34
|
+
|
|
35
|
+
Parse RNC compact syntax.
|
|
36
|
+
|
|
37
|
+
[source,ruby]
|
|
38
|
+
----
|
|
39
|
+
Rng.parse_rnc(rnc_text, location: nil)
|
|
40
|
+
----
|
|
41
|
+
|
|
42
|
+
**Parameters:**
|
|
43
|
+
|
|
44
|
+
- `rnc_text` (String) - The RNC compact syntax content
|
|
45
|
+
- `location` (String, optional) - File location for include resolution
|
|
46
|
+
|
|
47
|
+
**Returns:** `Rng::Grammar`
|
|
48
|
+
|
|
49
|
+
=== `Rng.to_rnc`
|
|
50
|
+
|
|
51
|
+
Convert a Grammar to RNC compact syntax.
|
|
52
|
+
|
|
53
|
+
[source,ruby]
|
|
54
|
+
----
|
|
55
|
+
Rng.to_rnc(grammar)
|
|
56
|
+
----
|
|
57
|
+
|
|
58
|
+
**Parameters:**
|
|
59
|
+
|
|
60
|
+
- `grammar` (Rng::Grammar) - The grammar to convert
|
|
61
|
+
|
|
62
|
+
**Returns:** String (RNC text)
|
|
63
|
+
|
|
64
|
+
=== `Rng::Grammar.from_xml`
|
|
65
|
+
|
|
66
|
+
Create a Grammar from XML.
|
|
67
|
+
|
|
68
|
+
[source,ruby]
|
|
69
|
+
----
|
|
70
|
+
Rng::Grammar.from_xml(xml_string)
|
|
71
|
+
----
|
|
72
|
+
|
|
73
|
+
=== `Rng::SchemaValidator.validate`
|
|
74
|
+
|
|
75
|
+
Validate an RNG schema.
|
|
76
|
+
|
|
77
|
+
[source,ruby]
|
|
78
|
+
----
|
|
79
|
+
Rng::SchemaValidator.validate(rng_xml)
|
|
80
|
+
----
|
|
81
|
+
|
|
82
|
+
**Raises:** `Rng::SchemaValidationError` if invalid
|
|
83
|
+
|
|
84
|
+
== Grammar Object Model
|
|
85
|
+
|
|
86
|
+
The gem uses Lutaml::Model for the object model. All classes inherit from `Lutaml::Model::Serializable`.
|
|
87
|
+
|
|
88
|
+
=== Core Classes
|
|
89
|
+
|
|
90
|
+
- `Rng::Grammar` - Root container
|
|
91
|
+
- `Rng::Start` - Entry point definition
|
|
92
|
+
- `Rng::Define` - Named pattern definitions
|
|
93
|
+
- `Rng::Element` - XML element patterns
|
|
94
|
+
- `Rng::Attribute` - XML attribute patterns
|
|
95
|
+
- `Rng::Group`, `Rng::Choice`, `Rng::Interleave` - Compositors
|
|
96
|
+
- `Rng::Optional`, `Rng::ZeroOrMore`, `Rng::OneOrMore` - Occurrence indicators
|
|
97
|
+
- `Rng::Ref`, `Rng::ParentRef`, `Rng::ExternalRef` - References
|
|
98
|
+
- `Rng::Text`, `Rng::Empty`, `Rng::NotAllowed` - Basic patterns
|
|
99
|
+
- `Rng::Value`, `Rng::Data`, `Rng::List` - Data patterns
|
|
100
|
+
|
|
101
|
+
=== Common Methods
|
|
102
|
+
|
|
103
|
+
All pattern objects support:
|
|
104
|
+
|
|
105
|
+
- `.to_xml` - Convert to XML string
|
|
106
|
+
- `.to_h` - Convert to hash representation
|
|
107
|
+
|
|
108
|
+
== Error Classes
|
|
109
|
+
|
|
110
|
+
=== `Rng::Error`
|
|
111
|
+
|
|
112
|
+
Base error class.
|
|
113
|
+
|
|
114
|
+
=== `Rng::SchemaValidationError`
|
|
115
|
+
|
|
116
|
+
Raised when schema validation fails.
|
|
117
|
+
|
|
118
|
+
=== `Rng::ExternalRefResolver::ExternalRefResolutionError`
|
|
119
|
+
|
|
120
|
+
Raised when external reference resolution fails.
|
|
121
|
+
|
|
122
|
+
[source,ruby]
|
|
123
|
+
----
|
|
124
|
+
error.href # => The href that failed
|
|
125
|
+
error.cause # => :circular, Errno::ENOENT, or nil
|
|
126
|
+
----
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: CLI Reference
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 2
|
|
5
|
+
parent: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= CLI Reference
|
|
9
|
+
|
|
10
|
+
The RNG gem includes a command-line interface for common tasks.
|
|
11
|
+
|
|
12
|
+
== Installation
|
|
13
|
+
|
|
14
|
+
The CLI is automatically installed with the gem:
|
|
15
|
+
|
|
16
|
+
[source,bash]
|
|
17
|
+
----
|
|
18
|
+
gem install rng
|
|
19
|
+
rng --version
|
|
20
|
+
----
|
|
21
|
+
|
|
22
|
+
== Global Options
|
|
23
|
+
|
|
24
|
+
[source,bash]
|
|
25
|
+
----
|
|
26
|
+
-v, --verbose # Verbose output
|
|
27
|
+
-q, --quiet # Suppress non-error output
|
|
28
|
+
-h, --help # Show help
|
|
29
|
+
--version # Show version number
|
|
30
|
+
----
|
|
31
|
+
|
|
32
|
+
== Commands
|
|
33
|
+
|
|
34
|
+
=== validate
|
|
35
|
+
|
|
36
|
+
Validate an XML document against a RELAX NG schema (replaces Jing).
|
|
37
|
+
|
|
38
|
+
[source,bash]
|
|
39
|
+
----
|
|
40
|
+
rng validate SCHEMA [DOCUMENT]
|
|
41
|
+
----
|
|
42
|
+
|
|
43
|
+
**Options:**
|
|
44
|
+
|
|
45
|
+
- `-c, --compact` - Schema is in RNC compact format
|
|
46
|
+
- `-x, --xml` - Schema is in RNG XML format (default: auto-detect)
|
|
47
|
+
- `-o, --output FORMAT` - Output format: text, xml, json
|
|
48
|
+
|
|
49
|
+
**Examples:**
|
|
50
|
+
|
|
51
|
+
[source,bash]
|
|
52
|
+
----
|
|
53
|
+
# Validate a schema
|
|
54
|
+
rng validate schema.rng
|
|
55
|
+
|
|
56
|
+
# Validate an XML document
|
|
57
|
+
rng validate schema.rng document.xml
|
|
58
|
+
|
|
59
|
+
# Validate with RNC schema
|
|
60
|
+
rng validate -c schema.rnc document.xml
|
|
61
|
+
----
|
|
62
|
+
|
|
63
|
+
=== convert
|
|
64
|
+
|
|
65
|
+
Convert between RNC and RNG formats (replaces Trang).
|
|
66
|
+
|
|
67
|
+
[source,bash]
|
|
68
|
+
----
|
|
69
|
+
rng convert INPUT [OUTPUT]
|
|
70
|
+
----
|
|
71
|
+
|
|
72
|
+
**Options:**
|
|
73
|
+
|
|
74
|
+
- `-I, --input-format FORMAT` - Input format: rng, rnc, auto
|
|
75
|
+
- `-O, --output-format FORMAT` - Output format: rng, rnc, auto
|
|
76
|
+
|
|
77
|
+
**Examples:**
|
|
78
|
+
|
|
79
|
+
[source,bash]
|
|
80
|
+
----
|
|
81
|
+
# RNC to RNG
|
|
82
|
+
rng convert schema.rnc -o schema.rng
|
|
83
|
+
|
|
84
|
+
# RNG to RNC
|
|
85
|
+
rng convert schema.rng schema_converted.rnc
|
|
86
|
+
----
|
|
87
|
+
|
|
88
|
+
=== parse
|
|
89
|
+
|
|
90
|
+
Parse a schema and display its structure.
|
|
91
|
+
|
|
92
|
+
[source,bash]
|
|
93
|
+
----
|
|
94
|
+
rng parse SCHEMA
|
|
95
|
+
----
|
|
96
|
+
|
|
97
|
+
**Options:**
|
|
98
|
+
|
|
99
|
+
- `-f, --format FORMAT` - Output format: text, json, yaml, xml
|
|
100
|
+
- `--ast` - Show abstract syntax tree (RNC only)
|
|
101
|
+
|
|
102
|
+
**Examples:**
|
|
103
|
+
|
|
104
|
+
[source,bash]
|
|
105
|
+
----
|
|
106
|
+
# Text output (default)
|
|
107
|
+
rng parse schema.rng
|
|
108
|
+
|
|
109
|
+
# JSON output
|
|
110
|
+
rng parse -f json schema.rng
|
|
111
|
+
----
|
|
112
|
+
|
|
113
|
+
=== info
|
|
114
|
+
|
|
115
|
+
Show information about a schema.
|
|
116
|
+
|
|
117
|
+
[source,bash]
|
|
118
|
+
----
|
|
119
|
+
rng info SCHEMA
|
|
120
|
+
----
|
|
121
|
+
|
|
122
|
+
**Options:**
|
|
123
|
+
|
|
124
|
+
- `--statistics` - Show pattern statistics
|
|
125
|
+
- `--namespaces` - List used namespaces
|
|
126
|
+
|
|
127
|
+
**Examples:**
|
|
128
|
+
|
|
129
|
+
[source,bash]
|
|
130
|
+
----
|
|
131
|
+
# Basic info
|
|
132
|
+
rng info schema.rng
|
|
133
|
+
|
|
134
|
+
# With statistics
|
|
135
|
+
rng info --statistics schema.rng
|
|
136
|
+
----
|
|
137
|
+
|
|
138
|
+
=== version
|
|
139
|
+
|
|
140
|
+
Show version number.
|
|
141
|
+
|
|
142
|
+
[source,bash]
|
|
143
|
+
----
|
|
144
|
+
rng version
|
|
145
|
+
----
|
|
146
|
+
|
|
147
|
+
== Exit Codes
|
|
148
|
+
|
|
149
|
+
- `0` - Success
|
|
150
|
+
- `1` - Invalid input or validation failure
|
|
151
|
+
- `2` - Error (file not found, parse error, etc.)
|
|
152
|
+
|
|
153
|
+
== Examples
|
|
154
|
+
|
|
155
|
+
=== Validate a document
|
|
156
|
+
|
|
157
|
+
[source,bash]
|
|
158
|
+
----
|
|
159
|
+
$ rng validate spec/fixtures/rng/xhtml.rng spec/fixtures/xhtml/sample.xml
|
|
160
|
+
Validating spec/fixtures/rng/xhtml.rng against spec/fixtures/xhtml/sample.xml...
|
|
161
|
+
Document is valid
|
|
162
|
+
----
|
|
163
|
+
|
|
164
|
+
=== Convert a schema
|
|
165
|
+
|
|
166
|
+
[source,bash]
|
|
167
|
+
----
|
|
168
|
+
$ rng convert spec/fixtures/rng/address_book.rng -o /tmp/address_book.rnc
|
|
169
|
+
Converting spec/fixtures/rng/address_book.rng (rng) to rnc...
|
|
170
|
+
Written to /tmp/address_book.rnc
|
|
171
|
+
----
|
|
172
|
+
|
|
173
|
+
=== Inspect a schema
|
|
174
|
+
|
|
175
|
+
[source,bash]
|
|
176
|
+
----
|
|
177
|
+
$ rng parse spec/fixtures/rng/address_book.rng
|
|
178
|
+
Schema Structure:
|
|
179
|
+
Start: Start
|
|
180
|
+
Definitions:
|
|
181
|
+
cardContent: element
|
|
182
|
+
----
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Architecture
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 3
|
|
5
|
+
parent: Understanding
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Architecture
|
|
9
|
+
|
|
10
|
+
The RNG gem has two parsing paths and one generation path.
|
|
11
|
+
|
|
12
|
+
== RNG XML Parsing
|
|
13
|
+
|
|
14
|
+
[source]
|
|
15
|
+
----
|
|
16
|
+
Rng.parse() → Grammar.from_xml() → Lutaml::Model with Nokogiri adapter
|
|
17
|
+
----
|
|
18
|
+
|
|
19
|
+
All RNG model classes inherit from `Lutaml::Model::Serializable` and define XML mappings via the `xml do` block.
|
|
20
|
+
|
|
21
|
+
== RNC Compact Parsing
|
|
22
|
+
|
|
23
|
+
[source]
|
|
24
|
+
----
|
|
25
|
+
Rng.parse_rnc() → RncParser.parse() → ParseTreeProcessor.normalize()
|
|
26
|
+
→ RncToRngConverter.convert() → Grammar.from_xml()
|
|
27
|
+
----
|
|
28
|
+
|
|
29
|
+
The RNC parser is a Parslet-based PEG parser in `lib/rng/rnc_parser.rb`.
|
|
30
|
+
|
|
31
|
+
== RNG to RNC Generation
|
|
32
|
+
|
|
33
|
+
[source]
|
|
34
|
+
----
|
|
35
|
+
Rng.to_rnc() → ToRnc.convert() → RncBuilder.build()
|
|
36
|
+
----
|
|
37
|
+
|
|
38
|
+
`RncBuilder` traverses the object model and generates RNC text.
|
|
39
|
+
|
|
40
|
+
== Object Model Structure
|
|
41
|
+
|
|
42
|
+
The object model mirrors RELAX NG concepts:
|
|
43
|
+
|
|
44
|
+
- `Grammar` - Root container
|
|
45
|
+
- `Start` - Entry point definition
|
|
46
|
+
- `Define` - Named pattern definitions
|
|
47
|
+
- `Element`, `Attribute` - XML structures
|
|
48
|
+
- Pattern classes: `Choice`, `Group`, `Interleave`, `Mixed`, `Optional`, `ZeroOrMore`, `OneOrMore`, `Text`, `Empty`, `Value`, `Data`, `List`
|
|
49
|
+
- Reference classes: `Ref`, `ParentRef`, `ExternalRef`
|
|
50
|
+
- Name classes: `Name`, `AnyName`, `NsName`, `Except`
|
|
51
|
+
- `Div` - Documentation and grouping container
|
|
52
|
+
|
|
53
|
+
== Dependencies
|
|
54
|
+
|
|
55
|
+
- **lutaml-model** - Object model and XML serialization
|
|
56
|
+
- **nokogiri** - XML parsing and building
|
|
57
|
+
- **parslet** - RNC compact syntax parser
|
|
58
|
+
- **canon** - XML comparison matchers for tests
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: RNG vs RNC
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 1
|
|
5
|
+
parent: Understanding
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= RNG vs RNC
|
|
9
|
+
|
|
10
|
+
RELAX NG schemas can be written in two formats: XML (RNG) and Compact (RNC).
|
|
11
|
+
|
|
12
|
+
== RNG XML Format
|
|
13
|
+
|
|
14
|
+
RNG is the XML-based representation of RELAX NG schemas.
|
|
15
|
+
|
|
16
|
+
=== Example
|
|
17
|
+
|
|
18
|
+
[source,xml]
|
|
19
|
+
----
|
|
20
|
+
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
|
|
21
|
+
<start>
|
|
22
|
+
<element name="person">
|
|
23
|
+
<zeroOrMore>
|
|
24
|
+
<element name="child">
|
|
25
|
+
<empty/>
|
|
26
|
+
</element>
|
|
27
|
+
</zeroOrMore>
|
|
28
|
+
</element>
|
|
29
|
+
</start>
|
|
30
|
+
</grammar>
|
|
31
|
+
----
|
|
32
|
+
|
|
33
|
+
=== Advantages
|
|
34
|
+
|
|
35
|
+
- **Standard XML tools**: Can be edited with any XML editor
|
|
36
|
+
- **Explicit structure**: All elements and attributes are visible
|
|
37
|
+
- **Namespaces**: Full namespace support is natural
|
|
38
|
+
- **Transformation**: Can be processed with XSLT
|
|
39
|
+
- **Validation**: Can be validated with XML schemas
|
|
40
|
+
|
|
41
|
+
=== Disadvantages
|
|
42
|
+
|
|
43
|
+
- **Verbose**: More characters to type
|
|
44
|
+
- **Less readable**: Harder to scan quickly
|
|
45
|
+
- **XML overhead**: Requires proper escaping
|
|
46
|
+
|
|
47
|
+
== RNC Compact Syntax
|
|
48
|
+
|
|
49
|
+
RNC is a text-based shorthand for RELAX NG schemas.
|
|
50
|
+
|
|
51
|
+
=== Example
|
|
52
|
+
|
|
53
|
+
[source,rnc]
|
|
54
|
+
----
|
|
55
|
+
element person {
|
|
56
|
+
element child {
|
|
57
|
+
empty
|
|
58
|
+
}*
|
|
59
|
+
}
|
|
60
|
+
----
|
|
61
|
+
|
|
62
|
+
=== Advantages
|
|
63
|
+
|
|
64
|
+
- **Concise**: Much shorter than equivalent XML
|
|
65
|
+
- **Readable**: Easier to see the structure at a glance
|
|
66
|
+
- **Programming-like**: Familiar syntax for developers
|
|
67
|
+
- **Quick prototyping**: Faster to write and modify
|
|
68
|
+
|
|
69
|
+
=== Disadvantages
|
|
70
|
+
|
|
71
|
+
- **No native tools**: Requires conversion for XML tools
|
|
72
|
+
- **Escaping**: Special characters need escaping
|
|
73
|
+
- **Limited namespace support**: More complex namespace handling
|
|
74
|
+
|
|
75
|
+
== When to Use Each
|
|
76
|
+
|
|
77
|
+
=== Use RNG when:
|
|
78
|
+
|
|
79
|
+
- You need to validate the schema itself with XML tools
|
|
80
|
+
- You're integrating with XML processing pipelines
|
|
81
|
+
- Namespace handling is critical
|
|
82
|
+
- You need to embed schema documentation in foreign elements
|
|
83
|
+
- You're working with teams more familiar with XML
|
|
84
|
+
|
|
85
|
+
=== Use RNC when:
|
|
86
|
+
|
|
87
|
+
- You want a quick prototype
|
|
88
|
+
- The schema is primarily for Ruby processing
|
|
89
|
+
- Readability is more important than tool compatibility
|
|
90
|
+
- You're writing tests or examples
|
|
91
|
+
|
|
92
|
+
== Conversion
|
|
93
|
+
|
|
94
|
+
Both formats are fully equivalent - you can convert between them without loss:
|
|
95
|
+
|
|
96
|
+
[source,ruby]
|
|
97
|
+
----
|
|
98
|
+
# RNG to RNC
|
|
99
|
+
grammar = Rng.parse(rng_xml)
|
|
100
|
+
rnc = Rng.to_rnc(grammar)
|
|
101
|
+
|
|
102
|
+
# RNC to RNG
|
|
103
|
+
grammar = Rng.parse_rnc(rnc_text)
|
|
104
|
+
rng_xml = grammar.to_xml
|
|
105
|
+
----
|
|
106
|
+
|
|
107
|
+
== Quick Reference
|
|
108
|
+
|
|
109
|
+
| Feature | RNG | RNC |
|
|
110
|
+
|---------|-----|-----|
|
|
111
|
+
| Element | `<element name="foo">...</element>` | `element foo { ... }` |
|
|
112
|
+
| Attribute | `<attribute name="bar">...</attribute>` | `attribute bar { ... }` |
|
|
113
|
+
| Optional | `<optional>...</optional>` | `... ?` |
|
|
114
|
+
| Zero or more | `<zeroOrMore>...</zeroOrMore>` | `... *` |
|
|
115
|
+
| One or more | `<oneOrMore>...</oneOrMore>` | `... +` |
|
|
116
|
+
| Choice | `<choice>...</choice>` | `... \| ...` |
|
|
117
|
+
| Sequence | `<group>...</group>` | `..., ...` |
|
|
118
|
+
| Interleave | `<interleave>...</interleave>` | `... & ...` |
|