Schematron / schematron

Schematron "skeleton" - XSLT implementation
MIT License
93 stars 45 forks source link

xsl:key with sequence-constructor instead of @use-attribute ist not handeled by skeleton correctly #86

Open hschmull opened 4 years ago

hschmull commented 4 years ago

As pointed out in #42 xsl:key should be used in Schematron without restrictions.

When I use an xsl:key with a sequence-constructor as content instead of a @use-attribute I get the error:

An xsl:key element must either have a @use attribute or have content

seems the content is ignored by skeleton. When I rewrite my key, putting the sequence-constructor in an xsl:function and refer it in a @use-attribute ecerythin works as expected.

My Example:

    <xsl:key name="verzeichnisse" match="/projekt/werk//
        *[local-name() = ('bild','formel','tabelle','video','audio','popup_inline') or meta/nachweis]
        [not(self::ausgabe_verzeichnis | self::ausgabe_index | self::ausgabe_definitionen | ancestor::alternativinhalt)]">
        <xsl:choose>
            <xsl:when test="self::bild[not( @verzeichnis = ('nein', 'tabelle', 'formel') )]
                |  (self::formel | self::tabelle)[@verzeichnis = 'abbildung']">
                <xsl:sequence select="'abbildung'"/>
            </xsl:when>
            <!-- ... -->
            <xsl:when test="self::video | self::audio | self::popup_inline">
                <xsl:sequence select="local-name()"/>
            </xsl:when>
        </xsl:choose>
    </xsl:key>

does not work, but:

    <xsl:key name="verzeichnisse" match="/projekt/werk//
        *[local-name() = ('bild','formel','tabelle','video','audio','popup_inline') or meta/nachweis]
        [not(self::ausgabe_verzeichnis | self::ausgabe_index | self::ausgabe_definitionen | ancestor::alternativinhalt)]" use="pa:keyVerzeichnis(.)"/>

    <xsl:function name="pa:keyVerzeichnis">
        <xsl:param name="element" as="element()"/>
        <xsl:choose>
            <xsl:when test="$element/(self::bild[not( @verzeichnis = ('nein', 'tabelle', 'formel') )]
                |  (self::formel | self::tabelle)[@verzeichnis = 'abbildung'])">
                <xsl:sequence select="'abbildung'"/>
            </xsl:when>
            <!-- ... -->
            <xsl:when test="$element/(self::video | self::audio | self::popup_inline)">
                <xsl:sequence select="$element/local-name()"/>
            </xsl:when>
        </xsl:choose>
    </xsl:function>

does – which took a bit of otherwise unnecessary refactoring.

dmj commented 4 years ago

I added a conformance test for this: https://github.com/Schematron/schematron-conformance/commit/71b846813ae2ea9c5a7a9cafb7c6d1c4e8ef03d4

hschmull commented 4 years ago

Thank you, David.