RJ7
RJ7

Reputation: 923

Is it possible to get the full xpath within a schematron rule?

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

Answers (2)

Nico Kutscherauer
Nico Kutscherauer

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

Joshua Legler
Joshua Legler

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

Related Questions