Using rnginline From the Command Line¶
Firstly, ensure you’ve installed rnginline.
Basic Usage¶
Basic usage is:
$ rnginline my-nested-schema-root.rng flattened-output.rng
If the second argument is not given, output goes to stdout, so you can pipe it
through xmllint --format
or similar:
$ rnginline schema.rng | xmllint --format -
<grammar xmlns="http://...
rnginline -h
gives help output as you’d expect, listing all available
options:
$ rnginline -h
Flatten a hierachy of RELAX NG schemas into a single schema by recursively
inlining <include>/<externalRef> elements.
usage: rnginline [options] <rng-src> [<rng-output>]
rnginline [options] --stdin [<rng-output>]
[...]
Full Example¶
In this example we create schema.rng
, which references external.rng
and
inline them into one file, tidying the output with xmllint
:
$ cat > schema.rng <<'EOF'
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<include href="external.rng">
<!-- Override foo -->
<define name="foo">
<element name="foo">
<value>abc</value>
</element>
</define>
</include>
<start>
<element name="root">
<ref name="foo"/>
<ref name="bar"/>
</element>
</start>
</grammar>
EOF
$ cat > external.rng <<'EOF'
<rng:grammar xmlns:xyz="x:/my/ns" xmlns:rng="http://relaxng.org/ns/structure/1.0">
<rng:define name="foo">
<rng:element name="foo">
<rng:notAllowed/> <!-- No foo for you! -->
</rng:element>
</rng:define>
<rng:define name="bar">
<rng:element name="xyz:bar">
<rng:text/>
</rng:element>
</rng:define>
</rng:grammar>
EOF
Flatten schema.rng
and everything it includes into a single XML document,
re-indent it with xmllint
and save the output in out.rng
:
$ rnginline schema.rng | xmllint --format - > out.rng
$ cat out.rng
<?xml version="1.0"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<div>
<rng:div xmlns:xyz="x:/my/ns" xmlns:rng="http://relaxng.org/ns/structure/1.0">
<rng:define name="bar">
<rng:element name="xyz:bar">
<rng:text/>
</rng:element>
</rng:define>
</rng:div>
<!-- Override foo -->
<define name="foo">
<element name="foo">
<value datatypeLibrary="">abc</value>
</element>
</define>
</div>
<start>
<element name="root">
<ref name="foo"/>
<ref name="bar"/>
</element>
</start>
</grammar>
The resulting schema acts as expected — the foo
definition from
external.rng
has been overridden:
$ xmllint --relaxng out.rng - <<'EOF'
<root>
<foo>abc</foo>
<bar xmlns="x:/my/ns">123</bar>
</root>
EOF
<?xml version="1.0"?>
<root>
<foo>abc</foo>
<bar xmlns="x:/my/ns">123</bar>
</root>
- validates
Advanced Usage¶
This section describes some less common use cases.
Passing the input on stdin¶
You can send the root schema on stdin, but doing so means rnginline won’t know
the location of the file, which means it can’t resolve relative references in
the input without extra information. To prevent casual use of stdin without
realising the issues, the --stdin
option must be passed in place of the
input file.
To tell rnginline where the schema on stdin is from, use the --base-uri
option. If you don’t specify a base, the paths of included files will be
relative to the current directory.
Here’s a (contrived) example of pre-processing the input before passing it on stdin:
$ xmllint --format - < /tmp/schema.rnc | rnginline --base-uri /tmp/schema.rnc --stdin
<grammar xmlns="http://...