Reputation: 923
I'd like to output some context within an abstracted schematron rule.
Example XML
...
<xpath>
<to>
<search>Content</search>
</to>
</xpath>
Schematron
<sch:rule context="$element">
<sch:report test="true()">
<sch:value-of select="$element"/>
</sch:report>
</sch:rule>
<sch:pattern id="tests-1" is-a="test">
<sch:param name="element" value="//xpath//to//search"/>
</sch:pattern>
...
Outputs Content
, is there anyway to get the xpath value //xpath//to//search
passed in?
Upvotes: 2
Views: 751
Reputation: 340
You need an abstract Schematron pattern for this. So this
<sch:pattern id="test" abstract="true">
<sch:rule context="$element">
<sch:report test="true()">
<sch:value-of select="$element"/>
</sch:report>
</sch:rule>
</sch:pattern>
<sch:pattern id="tests-1" is-a="test">
<sch:param name="element" value="//xpath//to//search"/>
</sch:pattern>
should work.
EDIT: Pleae note, that your example expression should work, but not every XPath expression is allowed in @context
of sch:rule
(actually it is called XSLT pattern).
Allowed Expressions:
//node
node/to/path
node/to/@attribute
node[following-sibling::any/xpath or function-call()]
node|otherNode
Prohibited Expressions:
/node/following-sibling::other/node
//node/ancestor::node
function-call()
to/be or not/to/be
Read more here: https://www.w3.org/TR/xslt20/#patterns
EDIT2: If you want to have the non-evaluated XPath expression it self as the error message, you can use this:
<sch:report test="true()">
<sch:value-of select=" '$element' "/>
</sch:report>
This works, because the parameters of abstract patterns will be replaced before the XPath expressions will be evaluated.
Please note, that this works only if the XPath expression it self does not contain a quote (e.g. node[@attribute = 'value']
).
Upvotes: 1
Reputation: 246
If you're using the XSLT-based reference implementation of Schematron to generate SVRL output, then the SVRL will include the XPath of the context of the successful report, like this:
<svrl:successful-report ... location="[this is where the XPath will be]">
If that doesn't address your need and you still need to get the XPath of a node, and you're using the XSLT-based reference implementation, you can take advantage of an XSL template that is defined in the implementation, like this:
<sch:pattern>
<sch:rule context="//xpath//to//search">
<sch:report test="true()">
<xsl:apply-templates select="." mode="schematron-get-full-path"/>
</sch:report>
</sch:rule>
</sch:pattern>
In order to do this, you have to use the allow-foreign
parameter when you compile the Schematron schema into XSLT, like this if you're using Saxon:
[path/to/saxon/]Transform
–xsl:iso-schematron-xslt2\iso_svrl_for_xslt2.xsl
–s:[SchematronFile2.sch]
–o:[SchematronFile.xsl]
allow-foreign=true
This approach would make your Schematron schema dependent upon the XSLT-based reference implementation of Schematron. Other implementations may not have the necessary XSL template.
Upvotes: 1