Desperately trying to get Schematron to alert only if the EFFECT element resides between two SUBTASK elements - they are siblings to each other. Greatly appreciate any assistance and please let me know if more information is needed.
Here is some simple sample code:
<TOPIC>
<SUBTASK></SUBTASK>
<EFFECT></EFFECT>
<SUBTASK></SUBTASK>
</TOPIC>
Here are two of my Schematron attempts - the problem is its alerting on every EFFECT within the document instead of just between the two SUBTASK. *note - EFFECT is a wildcard and allowed everywhere.
<rule context="EFFECT">
<assert test="preceding-sibling::*[position()[1]][SUBTASK] = following-sibling::*[position()[1]][SUBTASK]" role="error" id="error_EFFECT_between_SUBTASK"
>EFFECT not allowed between two SUBTASKs</assert>
</rule>
<rule context="EFFECT">
<assert test="count(preceding-sibling::*[position()>0]) and preceding-sibling::*[position()[1]][SUBTASK] = following-sibling::*[position()[1]][SUBTASK]" role="error" id="error_EFFECT_between_SUBTASKs"
>EFFECT not allowed between two SUBTASK</assert>
</rule>
You had most of the pieces, but lacked self::
for the 'self' axis. Try (untested):
<rule context="EFFECT">
<assert test="preceding-sibling::*[1][self::SUBTASK] and
following-sibling::*[1][self::SUBTASK]"
role="error" id="error_EFFECT_between_SUBTASKs"
>EFFECT not allowed between two SUBTASK</assert>
</rule>
[SUBTASK]
is true if there is a SUBTASK
child, not if the context element is a SUBTASK
.
[position()[1]]
would probably be an error is XPath 1.0, but in XPath 2.0 or XPath 3.0, it would be true every time because position()
returns a non-zero number, and the [1]
reduces the singe-item sequence of numbers to the first (and only) number in the sequence.