I am currently working on a simple schema with schematron rules embedded. One of the rules is to check the value of an attribute on a specific element called @handle
which should start with 12345 for example. But if that same element has another optional attribute called @remark
this rule doesn't apply as the value would be random.
I have the following XML:
<record handle="12345/random numbers"/>
<record handle="abcdef" remark="value"/>
And the following schema snippet:
<xs:element name="record">
<xs:annotation>
<xs:appinfo>
<sch:pattern id="handle check"
xmlns:sch="http://purl.oclc.org/dsdl/schematron">
<sch:rule context="@handle and not(../@remark)">
<sch:assert test="starts-with(.,'12345')">Handle-id, should start with 12345</sch:assert>
</sch:rule>
</sch:pattern>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="title" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="material" use="optional"/>
<xs:attribute name="remark" type="coll:remark" use="optional"/>
<xs:attribute name="handle" use="required">
</xs:attribute>
</xs:complexType>
</xs:element>
But using this I get stylesheet compilation errors. If I delete the part and not(../@remark)
, it works fine and creates errors at the elements with @remark
like expected, but I cannot seem to exclude this and am wondering if this is even possible.
The @context
of a rule
must refer to a node. @handle
is a node, and @remark
is also a node, but @handle and not(../@remark)
is an expression that evaluates to true or false. It's not a node.
You could rewrite the rule/@context
to be:
@handle[not(../@remark)]
... which would fire on all @handle
attribute nodes that do not have a @remark
sibling attribute.