Reputation: 87
So I'm trying to use a schematron to validate an XML. from the XdmNode
I'm getting the following warning
!--WARNING: Rule for context "test:responseTest" shadowed by preceding rule-->
this is when looping through all the XdmNodes from the rootnode
for (XdmNode node : rootnode.children().iterator().next().children()) {
if(node.getNodeKind() == XdmNodeKind.COMMENT) {
continue;
}
}
is this an issue with the schematron or how do I fix this?
Upvotes: 0
Views: 156
Reputation: 167401
I see this warning in a Schxslt generated SVRL report if I duplicate a rule with the same context
inside of a pattern
e.g.
<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3">
<pattern>
<rule context="root">
<assert test="@*">root has no attributes.</assert>
</rule>
<rule context="root">
<assert test="@*">root has no attributes.</assert>
</rule>
</pattern>
</schema>
when applied on
<root>This is an example.</root>
generates a report like
<svrl:schematron-output xmlns:error="https://doi.org/10.5281/zenodo.1495494#error" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:schxslt-api="https://doi.org/10.5281/zenodo.1495494#api" xmlns:schxslt="https://doi.org/10.5281/zenodo.1495494" xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<svrl:metadata xmlns:dct="http://purl.org/dc/terms/" xmlns:skos="http://www.w3.org/2004/02/skos/core#">
<dct:creator>
<dct:Agent>
<skos:prefLabel>SaxonJS/2.5</skos:prefLabel>
</dct:Agent>
</dct:creator>
<dct:created>2023-06-22T16:19:23.998+02:00</dct:created>
<dct:source>
<rdf:Description xmlns:dc="http://purl.org/dc/elements/1.1/">
<dct:creator>
<dct:Agent>
<skos:prefLabel>SchXslt/1.9.3 SaxonJS/2.5</skos:prefLabel>
<schxslt.compile.typed-variables xmlns="https://doi.org/10.5281/zenodo.1495494#">true</schxslt.compile.typed-variables>
</dct:Agent>
</dct:creator>
<dct:created>2023-06-22T16:19:23.716+02:00</dct:created>
</rdf:Description>
</dct:source>
</svrl:metadata>
<svrl:active-pattern documents="https://martin-honnen.github.io/schematron-fiddle/schxslt/1.9.3/run-pipeline-for-svrl-and-apply-to-schema.sef.json"/>
<svrl:fired-rule context="root"/>
<svrl:failed-assert location="/Q{}root[1]" test="@*">
<svrl:text>root has no attributes.</svrl:text>
</svrl:failed-assert>
<!--WARNING: Rule for context "root" shadowed by preceding rule--><svrl:suppressed-rule context="root"/>
</svrl:schematron-output>
which is basically an attempt by Schxslt to point out that the second assert
is not taken into account as only the first match is used; depending on your intentions and schema and instance documents this might happen but it could also be a coding error in the Schematron schema so I think the warning is helpful in that case.
Schxslt has a parameter <xsl:param name="schxslt.svrl.compact" as="xs:boolean" select="false()"/>
that by default is false, if you set it to true()
then I think warning and suppressed-rule output will not occur.
As for the question in a comment as to which line a suppressed-rule refers to, it appears that the Schematron SVRL or Schxslt implementation doesn't assume you want e.g. a location
attribute on those elements but it is easy to change or override two templates in svrl.xsl
of Schxslt to do e.g.
<xsl:template name="schxslt-api:fired-rule">
<xsl:param name="rule" as="element(sch:rule)" required="yes"/>
<xsl:param name="location-function" as="xs:string" required="yes" tunnel="yes"/>
<xsl:if test="$schxslt.svrl.compact eq false()">
<svrl:fired-rule location="{{{$location-function}({('.')[1]})}}">
<xsl:sequence select="($rule/@id, $rule/@role, $rule/@flag, $rule/@see, $rule/@icon, $rule/@fpi, $rule/@xml:*)"/>
<attribute name="context">
<xsl:value-of select="$rule/@context"/>
</attribute>
</svrl:fired-rule>
</xsl:if>
</xsl:template>
<xsl:template name="schxslt-api:suppressed-rule">
<xsl:param name="rule" as="element(sch:rule)" required="yes"/>
<xsl:param name="location-function" as="xs:string" required="yes" tunnel="yes"/>
<xsl:if test="$schxslt.svrl.compact eq false()">
<xsl:variable name="message">
WARNING: Rule <xsl:value-of select="normalize-space(@id)"/> for context "<xsl:value-of select="@context"/>" shadowed by preceding rule
</xsl:variable>
<comment> <xsl:sequence select="normalize-space($message)"/> </comment>
<svrl:suppressed-rule location="{{{$location-function}({('.')[1]})}}">
<xsl:sequence select="($rule/@id, $rule/@role, $rule/@flag, $rule/@see, $rule/@icon, $rule/@fpi)"/>
<attribute name="context">
<xsl:value-of select="$rule/@context"/>
</attribute>
</svrl:suppressed-rule>
</xsl:if>
</xsl:template>
then you get output like e.g. <svrl:fired-rule location="/Q{}root[1]" context="*"/>
and <svrl:suppressed-rule location="/Q{}root[1]/Q{}item[1]" context="*"/>
.
Upvotes: 0