0

I have a schematron-file looking like this (as simply as possible)

    <sch:pattern id="TDOP_0400">
            <sch:rule context="//tekst:Kop">
                 <xsl:variable name="CONDITION"> 
                        <xsl:value-of select="tekst:Label and tekst:Opschrift and tekst:Nummer"/>
                 </xsl:variable>
            </sch:rule>
    </sch:pattern>

When I run it in Oxygen, it runs fine, but when I run it from the commandline I get an error. This is my commandline command:

$ java -cp ../saxon9.9.1.5/saxon9he.jar net.sf.saxon.Transform -t -s:tpod0400.sch -xsl:../saxon9.9.1.5/iso_svrl_for_xslt2.xsl -o:tpod0400.xsl

This is the error message, I get it for every xsl:variable-line:

Warning: unrecognized element xsl:variable
Bert Verhees
  • 1,057
  • 3
  • 14
  • 25

2 Answers2

1

Add "allow-foreign=true" to the command:

$ java -cp ../saxon9.9.1.5/saxon9he.jar net.sf.saxon.Transform -t -s:tpod0400.sch -xsl:../saxon9.9.1.5/iso_svrl_for_xslt2.xsl -o:tpod0400.xsl allow-foreign=true

"allow-foreign" is a parameter in iso_svrl_for_xslt2.xsl, which is documented as follows in the stylesheet:

Pass non-Schematron elements and rich markup to the generated stylesheet

xsl:variable is a non-Schematron element and is left out unless allow-foreign=true.

Joshua Legler
  • 236
  • 1
  • 5
  • Thanks, I appreciate your reply, although I found another solution by extracting the needed xsl-code to separate functions. Your answer might be welcome when my solution is not possible. – Bert Verhees Mar 02 '20 at 06:35
0

Best and most safe practice is to separate sch (schematron) from xslt code. Keep the sch-code inside the rule, and if you need xslt-functionality, break out with a function call to xslt-code, then return the result of the funtion back to the sch-code, and go on with sch-processing.

So short: Never mix up sch and xslt in one programming context, and you will always be safe.

I have an example, never mind what it does or what it is for, it is here to demonstrate how to break out an sch-context to invoke some xslt-code, and then return back to the sch-context:

<sch:pattern id="TPOD_0520">
    <sch:rule context="//tekst:Hoofdstuk/tekst:Titel">
        <sch:let name="APPLICABLE"
            value="$SOORT_REGELING = $OP or $SOORT_REGELING = $OV or $SOORT_REGELING = $WV"/>
        <sch:let name="hoofdstuk" value="string(../tekst:Kop/tekst:Nummer)"/>
        <sch:let name="titel" value="string(tekst:Titel/tekst:Kop/tekst:Nummer)"/>

<!-- Below is the break-out to XSLT, and the value coming from the function is used in the sch-code -->

        <sch:let name="volgorde" value="foo:volgordeTPOD_0520($titel, .)"/>
        <sch:let name="CONDITION" value="string-length($volgorde) = 0"/>
        <sch:assert test="($APPLICABLE and $CONDITION) or not($APPLICABLE)"> 
            TPOD_0520: Als tussen Hoofdstuk en Afdeling Titel voorkomt dan moet de nummering van Afdelingen beginnen met het samengestelde nummer van de Titel waarin de Afdeling voorkomt, gevolgd door een punt. (betreft hoofdstukken, titels, afdelingen):  <xsl:value-of select="$hoofdstuk"/>: <sch:value-of select="$titel"/>: <sch:value-of select="substring($volgorde,1,string-length($volgorde)-2)"/></sch:assert>
    </sch:rule>
</sch:pattern>

<xsl:function name="foo:volgordeTPOD_0520">
    <xsl:param name="titel" as="xs:string"/>
    <xsl:param name="context" as="node()"/>
    <xsl:variable name="volgorde">
        <xsl:for-each select="$context/tekst:Afdeling">
            <xsl:if test="not(string(tekst:Kop/tekst:Nummer)=concat($titel, '.', string(position())))">
                <xsl:value-of select="concat(string(tekst:Kop/tekst:Nummer),', ')"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    <xsl:value-of select="$volgorde"/>
</xsl:function>
Bert Verhees
  • 1,057
  • 3
  • 14
  • 25