Im working to automate the testing of an API which takes and returns XML, so I want to translate the documented return data of the API into schema as much as possible. I cho
See if the following schema helps
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="item">
<interleave>
<element name="id"><text/>
</element>
<element name="name"><text/></element>
<oneOrMore>
<ref name="link"/>
</oneOrMore>
</interleave>
</element>
</start>
<define name="link">
<element name="link">
<attribute name="href"/>
<choice>
<group>
<attribute name="rel"><value>self</value></attribute>
<attribute name="type"><value>type1</value></attribute>
</group>
<group>
<attribute name="rel"><value>download</value></attribute>
<attribute name="type"><value>type2</value></attribute>
</group>
<group>
<attribute name="rel"><value>relatedData</value></attribute>
<attribute name="type"><value>type3</value></attribute>
</group>
</choice>
</element>
</define>
</grammar>
It looks like you have stumbled upon a restriction on interleave in RELAX NG. I would try to do this in Schematron, or perhaps a combination of RELAX NG and Schematron.
Here is a snippet that checks your <link>
elements using the version of Schematron that is supported by Jing:
<schema xmlns="http://www.ascc.net/xml/schematron">
<pattern name="link pattern">
<rule context="item">
<assert test='count(link) = 3'>There must be 3 link elements.</assert>
<assert test="count(link[@rel = 'self' and @type ='type1']) = 1">There must be 1 link element wwhere @rel='self' and @type='type1'.</assert>
<assert test="count(link[@rel = 'download' and @type ='type2']) = 1">There must be 1 link element where @rel='download' and @type='type2'.</assert>
<assert test="count(link[@rel = 'relatedData' and @type = 'type3']) = 1">There must be 1 link element where @rel='relatedData' and @type='type3'.</assert>
</rule>
</pattern>
</schema>