[relaxng-user] Recursive structure with restrictions
Tor Helland
tor at helland.org
Thu Jun 17 22:14:12 ICT 2004
Hi, I want to model a recursive structure with a choice of say 3 elements,
which again may contain that same choice as subelements. At least this is a
simple test case for the actual structure:
<container-abc>
<a>
<b>
<c/>
</b>
</a>
</container-abc>
or
<container-abc>
<c>
<b>
<a/>
</b>
</c>
</container-abc>
But I also want to reuse that structure in some other contexts, restricting
the allowed elements, without making a customised copy of the whole
definition:
<container-ab>
<a>
<b>
<!-- <c/> would be illegal -->
</b>
</a>
</container-ab>
or
<container-c>
<c>
<c>
<c/>
</c>
</c>
</container-c>
Playing with grammars, I found a solution demoed in the three documents at
the end of this email. I like the control I get over the structure, and not
repeating it.
Is there a better way to achieve this, preferrably with one schema file? Is
there a simpler way, something obvious I have overlooked?
-tor
test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<test xmlns="test">
<container-abc>
<a>
<b>
<c/>
</b>
</a>
</container-abc>
<container-ab>
<a>
<b>
<b/>
</b>
</a>
</container-ab>
<container-c>
<c>
<c>
<c/>
</c>
</c>
</container-c>
</test>
test.rng:
<?xml version="1.0" encoding="UTF-8"?>
<grammar ns="test" xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="test">
<empty/>
<ref name="container-abc-element"/>
<ref name="container-ab-element"/>
<ref name="container-c-element"/>
</element>
</start>
<define name="container-abc-element">
<grammar>
<include href="test2.rng"/>
<start>
<element name="container-abc">
<ref name="container-choice"/>
</element>
</start>
<define name="container-choice">
<choice>
<ref name="a-element"/>
<ref name="b-element"/>
<ref name="c-element"/>
</choice>
</define>
</grammar>
</define>
<define name="container-ab-element">
<grammar>
<include href="test2.rng"/>
<start>
<element name="container-ab">
<ref name="container-choice"/>
</element>
</start>
<define name="container-choice">
<choice>
<ref name="a-element"/>
<ref name="b-element"/>
</choice>
</define>
</grammar>
</define>
<define name="container-c-element">
<grammar>
<include href="test2.rng"/>
<start>
<element name="container-c">
<ref name="container-choice"/>
</element>
</start>
<define name="container-choice">
<choice>
<ref name="c-element"/>
</choice>
</define>
</grammar>
</define>
</grammar>
test2.rng:
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<define name="a-element">
<grammar>
<start>
<element name="a">
<empty/>
<optional>
<parentRef name="container-choice"/>
</optional>
</element>
</start>
</grammar>
</define>
<define name="b-element">
<grammar>
<start>
<element name="b">
<empty/>
<optional>
<parentRef name="container-choice"/>
</optional>
</element>
</start>
</grammar>
</define>
<define name="c-element">
<grammar>
<start>
<element name="c">
<empty/>
<optional>
<parentRef name="container-choice"/>
</optional>
</element>
</start>
</grammar>
</define>
</grammar>
More information about the relaxng-user
mailing list