Need a little recursion in RELAX NG external references
Question
We've been using RELAX NG to specify and validate XML messages for our web-based API, and I was doing some housecleaning and started to make use of the <external>
element.
In our schemas we have a <subscription>
element, which has things like id and a period and so on, and also an <account>
. This is pretty simple to spec in RELAX NG:
<?xml version="1.0"?>
<element name="subscription" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="id">
<text />
</element>
<zeroOrMore>
<externalRef href="./account.xml" />
</zeroOrMore>
</element>
This schema would then be included by the actual message schema for a particular request.
The problem is that the <account>
element can also have a number of <subscription>
elements depending on the request (for example, sometimes we are searching for subscription data based on account information, and sometimes we would be searching for account information based on subscription data).
I tried:
<?xml version="1.0"?>
<element name="account" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="id">
<text />
</element>
<zeroOrMore>
<externalRef href="./subscription.xml" />
</zeroOrMore>
</element>
But I got a (not unexpected) error when loading the schema: Detected an externalRef recursion
Is there a way to specify some kind of recursion limit - some way to know that my current <subscription>
is a child of <account>
and so should not have <account>
children itself?
Solution
As long as you point to the subscription
element defined in you first Relax NG, the substruture has to match the pattern you are pointing to.
To achieve your goal, you should have another pattern definition for another subscription
element with a different substructure.
Something like :
<define name="subscriptionDEF-2">
<element name="subscription">
<text/>
</element>
</define>
And refer to if from your account
element with a ref
element.
<element name="account">
<ref name="subscriptionDEF-2"/>
</element>