Re: [xsl] Can a single XPath statement duplicate the functionality of this verbose <xsl:choose> statement?

Subject: Re: [xsl] Can a single XPath statement duplicate the functionality of this verbose <xsl:choose> statement?
From: Andrew Welch <andrew.j.welch@xxxxxxxxx>
Date: Mon, 24 Oct 2011 11:17:58 +0100
On 24 October 2011 01:10, Mark <mark@xxxxxxxxxxxx> wrote:
> Although they do have the virtue of giving me my desired output, can the
> following sequence of statements be replaced by a more generalized (shorter
> and simpler) XPath statement without the repetitive "when" tests shown
> below?
>
> <xsl:choose>
>         <xsl:when test="@souvenir-sheet">
>           <xsl:copy-of select="if (../Location/@souvenir-sheet) then
> ../Location/@souvenir-sheet else if (../Location/@denomination) then
> ../Location/@denomination else '0' "/>
>         </xsl:when>
>         <xsl:when test="@minisheet">
>           <xsl:copy-of select="if(../Location/@minisheet) then
> ../Location/@minisheet else if(../Location/@denomination) then
> ../Location/@denomination else '0'"/>
>         </xsl:when>
>         <xsl:when test="@booklet">
>           <xsl:copy-of select="if(../Location/@booklet) then
> ../Location/@booklet else if(../Location/@denomination) then
> ../Location/@denomination else '0'"/>
>         </xsl:when>
>         <xsl:when test="@se-tenant">
>           <xsl:copy-of select="if (../Location/@se-tenant) then
> ../Location/@se-tenant else if(../Location/@denomination) then
> ../Location/@denomination else '0'"/>
>         </xsl:when>
>         <xsl:when test="@coupon">
>           <xsl:copy-of select=" if (../Location/@coupon) then
> ../Location/@coupon else if(../Location/@denomination) then
> ../Location/@denomination else '0'"/>
>         </xsl:when>
> </xsl:choose>

I would use templates for this, then its easier to maintain down the line:

Apply templates to the attributes:

<xsl:apply-templates select="@souvenir-sheet, @minisheet, @booklet"/>

(if you only want to process the first that exists and not all them
then use(@souvenir-sheet, @minisheet, @booklet)[1]

then use 3 templates to cover the 3 conditions, using the priority
attribute to control which gets matched:

<xsl:template match="@souvenir-sheet[../Location/@souvenir-sheet]"
priority="30">
    <xsl:value-of select="../Location/@souvenir-sheet"/>
</xsl:template>

<xsl:template match="@souvenir-sheet[../Location/@denomination]"
priority="20">
    <xsl:value-of select="../Location/@denomination"/>
</xsl:template>

<xsl:template match="@souvenir-sheet" priority="10">0</xsl:template>

Doing it that way instead of a single xpath should make it easier to
follow and debug, you can add additional conditions without touching
the existing code and you open up the code for overriding.

--
Andrew Welch
http://andrewjwelch.com

Current Thread