The requirement is as such:
- A feed will have multiple links
- A "B" type link MUST appear atleast once
- An "A" type link MAY appear zero or more times
- "A" type links can appear in other places too hence need to keep the define independent
I get the following error with the code
lxml.etree.RelaxNGParseError: Element or text conflicts in interleave, line 6
Example code below
from io import StringIO
from lxml import etree
XML = StringIO('''
<root xmlns="http://www.w3.org/2005/Atom">
<link rel="a1" />
<link rel="b1" />
<link rel="a2" />
<link rel="b2" />
</root>
''')
RNG = StringIO('''
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="root" ns="http://www.w3.org/2005/Atom">
<interleave>
<zeroOrMore>
<ref name="aLink"/>
</zeroOrMore>
<oneOrMore>
<ref name="bLink"/>
</oneOrMore>
</interleave>
</element>
</start>
<define name="aLink" ns="http://www.w3.org/2005/Atom">
<element name="link">
<choice>
<attribute name="rel">
<value>a1</value>
</attribute>
<attribute name="rel">
<value>a2</value>
</attribute>
</choice>
</element>
</define>
<define name="bLink" ns="http://www.w3.org/2005/Atom">
<element name="link">
<choice>
<attribute name="rel">
<value>b1</value>
</attribute>
<attribute name="rel">
<value>b2</value>
</attribute>
</choice>
</element>
</define>
</grammar>
''')
rng_tree = etree.parse(RNG)
rng_schema = etree.RelaxNG(rng_tree)
rng_schema.validate(XML)
I fear that it's a typical case that is forbidden by the specification of Relax NG
https://www.oasis-open.org/committees/relax-ng/spec-20011203.html#interleave-restrictions