I am still struggling with my XML Schema and I just do not seem to be able to get it right. I need to write an XSLT assertion to ensure that every nested <instruction> element has either a child element <stroke> or any ancestor has a <stroke> element (XOR).
This is an example of a valid XML:
<program>
<instruction>
<lengthAsDistance>100</lengthAsDistance>
<stroke>
<standardStroke>backstroke</standardStroke>
</stroke>
</instruction>
<instruction>
<repetition>
<repetitionCount>3</repetitionCount>
<stroke>
<standardStroke>freestyle</standardStroke>
</stroke>
<instruction>
<lengthAsDistance>100</lengthAsDistance>
</instruction>
<instruction>
<lengthAsDistance>200</lengthAsDistance>
</instruction>
<instruction>
<repetition>
<repetitionCount>4</repetitionCount>
<instruction>
<lengthAsDistance>100</lengthAsDistance>
</instruction>
</repetition>
</instruction>
</repetition>
</instruction>
</program>
I then tried:
<xs:assert test="(stroke and not(ancestor::stroke) or not(stroke) and ancestor::stroke) or (.. is root() and repetition)"/>
The test for the child element <stroke> works fine, but the test for any ancestors having a <stroke> child does not work as expected. The test for all <instruction> directly under the root <program> also does not seem to work.
Thank you up front for any help that you can offer.
I think in Schematron, where XPath can be used for assertions, you would want something like
For XSD 1.1 assertions, I am not sure how freely you can navigate around ancestors, with Saxon EE the following works for me: