Skip to content

Problem with xsl:choose #92

@JohnGlauert

Description

@JohnGlauert

I have a case where xsl:choose gives unexpected results but an equivalent pair of xsl:if elements works (using a browser solution with XSLTProcessor).

NOTE: I have corrected the text here. See later comment.

A cut down stylesheet working on:

<sign gloss="simple">
  <hamnosys_sign>
    <sign2>
      <minitialconfig2>
        <handconfig2>
          <handshape2>
            <handshape1 handshapeclass="ham_flathand"/>
          </handshape2>
        </handconfig2>
      </minitialconfig2>
    </sign2>
  </hamnosys_sign>
</sign>

should yield:

<hamgestural_sign>
  <sign_manual>
    <handconfig handshape="flat"/>
  </sign_manual>
</hamgestural_sign>

but yields:

<hamgestural_sign>
  <sign_manual>
    <handconfig>flat
    </handconfig>
  </sign_manual>
</hamgestural_sign>

Here is the (failing) stylesheet - cut back a lot:

<xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- THESE OUTPUT SETTINGS MAY BE OVERRIDDEN BY THE H2S PROCESSOR: -->

<xsl:output method="xml" omit-xml-declaration="yes"
    indent="yes" encoding="UTF-8"/>

<!--######## handShapeValue ########-->

<xsl:template name="handShapeValue">

    <xsl:variable name="hs" select="@handshapeclass"/>

<!-- OK
    <xsl:value-of select="substring-after(concat(substring-before($hs,'hand'),$hs[not(contains(.,'hand'))]),'ham_')"/>
-->

<!-- OK
    <xsl:if test="$hs='ham_flathand'">
        <xsl:value-of select="'flat'"/>
    </xsl:if>
    <xsl:if test="$hs!='ham_flathand'">
        <xsl:value-of select="substring-after($hs,'ham_')"/>
    </xsl:if>
-->
<!-- Fails -->
    <xsl:choose>
        <xsl:when test="$hs='ham_flathand'">
            <xsl:value-of select="'flat'"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="substring-after($hs,'ham_')"/>
        </xsl:otherwise>
    </xsl:choose>

<!-- Fails
    <xsl:choose>
        <xsl:when test="$hs='ham_flathand'">
            <xsl:value-of select="'flat'"/>
        </xsl:when>
    </xsl:choose>
 -->
 
</xsl:template>

<!--######## sign ########-->

<xsl:template match="/">
    <!--
    <!ELEMENT sign (hamnosys_sign?)>
    <!ATTLIST sign gloss CDATA #IMPLIED>
    -->

    <xsl:element name="hamgestural_sign">

        <xsl:if test="@gloss">
            <xsl:attribute name="gloss">
                <xsl:value-of select="@gloss"/>
            </xsl:attribute>
        </xsl:if>

        <xsl:element name="sign_manual">
            <xsl:apply-templates select="sign/hamnosys_sign/sign2/minitialconfig2/handconfig2/handshape2/handshape1"/>
        </xsl:element>

    </xsl:element>

</xsl:template>

<!--######## handshape1 ########-->

<xsl:template match="handshape1">
    <!--
    <!ELEMENT handshape1 (
        fingernothumb*, fingershape*, fingercrossing*, thumbspecial?
    )>
    <!ATTLIST handshape1
        handshapeclass (%handshapeclass;) #REQUIRED
        fingerbending (%fingerbending;) #IMPLIED
        thumbpos (%thumbpos;) #IMPLIED
        second_handshapeclass (%handshapeclass;) #IMPLIED
        second_fingerbending (%fingerbending;) #IMPLIED
        second_thumbpos (%thumbpos;) #IMPLIED
        approx_shape %boolfalse;
    >
    -->

    <xsl:element name="handconfig">

        <xsl:variable name="hs">
            <xsl:call-template name="handShapeValue"/>
        </xsl:variable>

        <!-- handshape ATTRIBUTE -->
        <xsl:attribute name="handshape">
            <xsl:value-of select="$hs"/>
        </xsl:attribute>

    </xsl:element>

</xsl:template>

</xsl:transform>

There are several alternatives in template 'handShapeValue': One using a complex XPath expression - works; one using xsl:if - works; some using xsl:choose - don't work.

Looking at the high level code, xsl:if looks simpler and straightforward, while xsl:choose seems to use a different evaluation context, which maybe does not work in my case.

There may be other cases where xslt-processor is not working with my stylesheet as some output is duplicated. However, this seems to be a simple case where I am doing something wrong or there is an issue. I could convert all xsl:choose cases to xsl:if (even using XSLT!) but would rather not. The underlying stylesheet is very old and has been used without problems for many years - but it is several thousand lines long.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions