phax / ph-schematron

Java Schematron library that supports XSLT and native application
Apache License 2.0
115 stars 36 forks source link

sch:diagnostics leads to errors with schematron engine #85

Closed nkutsche closed 3 years ago

nkutsche commented 5 years ago

Hi,

I tried to validate with this Schematron:

<sch:pattern>
        <sch:rule context="/">
            <sch:report test="true()" diagnostics="d1"/>
        </sch:rule>
    </sch:pattern>
    <sch:diagnostics>
        <sch:diagnostic id="d1" xml:lang="de">Foobar</sch:diagnostic>
    </sch:diagnostics>

using this Ant script (using ph-Schematron 5.2.0):

<taskdef name="schematron" classname="com.helger.schematron.ant.Schematron"/>

<target name="db.common.validation.schematron">
    <schematron schematronFile="test.sch" expectSuccess="true" failonerror="true"
        schematronProcessingEngine="schematron" svrlDirectory=".">
        <file file="test.xml"/>
    </schematron>
</target>

Instead of the expected error message I always get:

Invalid content was found starting with element 'svrl:diagnostic-reference'. No child element is expected at this point.

The problem seems to come from this SVRL-schema. There is already a note, which points to this issues:

<!-- Note: XSLT based version may emit the diagnostic-reference here :( -->

After a bit researching this seems to be a known gap between the ISO Schematron implementation and the ISO Schematron SVRL Schema. As I just found out you can avoid this error by setting the Skeleton parameter $diagnose=false. This turns off the diagnostic support but it doesn't work anyway.

I think the ph-schematron engine should force the $diagnose parameter value to false until the Skeleton is fixed, shouldn't it?

phax commented 3 years ago

It was quite tedious to find a matching XSD for this mess. But basically

      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="svrl:diagnostic-reference"/>
        <xs:element ref="svrl:property-reference"/>
        <xs:element ref="svrl:text"/>
        <!-- Note: XSLT based version may emit the diagnostic-reference here :( -->
      </xs:choice>

does the trick. There is more broken with the diagnostic references. Instead of using the <text> element, the ISO Schematron throws the text directly into the <diagnostic-reference> element. sigh

This will be part of the 6.0.2 release. In the meantime adding the custom XSLT parameter $diagnose=false should do the trick.