priyanka manogaran
priyanka manogaran

Reputation: 51

XSLT - How to apply if-else or choose-when for the below xml

I using the below xml,xslt where I want to check the condition as if attribute nominee start with '1 2' means then just get the value of the nominee else concat the '1 2' with nominee value

XML

<catalog>
<cd nominee ="1 2 First">
    <title company="Grammy" price="10.20">1999 Grammy Nominees</title>
    <artist all="type">Many</artist>
    <country>USA</country>
</cd>
<cd nominee ="Second">
    <title company="Grammy" price="20.20">Grammy Nominees</title>
    <artist all="type">Many</artist>
    <country>UK</country>
</cd>
</catalog>

XSLT

    <xsl:template match="catalog">
      <fo:block>
       <xsl:if test ="cd/@value">
        <xsl:if test="starts-with(., '1 2')">
                <xsl:value-of select="cd/@value" />
        </xsl:if>
       <xsl:if test="not(starts-with(.,'1 2'))">
           <xsl:value-of select="concat('1 2',cd/@value)" /> 
       </xsl:if> 
     </xsl:if>
  <xsl:apply-templates/>
</fo:block>
</xsl:template>

Tried this too

<xsl:template match="catalog">
      <fo:block>
    <xsl:choose>
       <xsl:when test ="cd/@value">
          <xsl:if test="starts-with(., '1 2')">
                <xsl:value-of select="cd/@value" />
          </xsl:if>
       </xsl:when>
       <xsl:otherwise>
           <xsl:value-of select="concat('1 2',cd/@value)" /> 
       </xsl:otherwise> 
     </xsl:choose>
  <xsl:apply-templates/>
</fo:block>
</xsl:template>

By using the above XSLT I'm Always getting false and get output as <fo:block>'1 2 1 2 First'</fo:block>

Output that I want is

First cd element

<fo:block>'1 2 First'</fo:block>

Second cd element

<fo:block>'1 2 Second'</fo:block>

Thanks !!

Upvotes: 0

Views: 68

Answers (1)

Michael Kay
Michael Kay

Reputation: 163587

You need to learn which XSLT instructions change the context, and which don't. Within a template rule with match="catalog", the context item is the catalog element, and it's not changed by xsl:when or xsl:if. So your test in the starts-with needs to select from the catalog element.

But it's a bit more subtle than this, because there is more than one cd (I assume you meant cd/@nominee rather than cd/@value, by the way).

The way to write this one is using template rules. What you really, want, I think, is something like:

<xsl:template match="catalog">
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="cd[starts-with(@nominee, '1 2')]">
   <xsl:value-of select="@nominee"/>
</xsl:template>

<xsl:template match="cd">
   <xsl:value-of select="concat('1 2 ', @nominee)"/>
</xsl:template>

Upvotes: 1

Related Questions