santi254
santi254

Reputation: 87

Saxon S9API Java, dealing with comments

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

Answers (1)

Martin Honnen
Martin Honnen

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

Related Questions