Working with xsl:choose in XSLT

This is the second article in a series focusing on developing XSLT-oriented applications using ASP.NET 2.0. Even though the series is based on ASP.NET 2.0, I use it only as a transformation engine. The entire focus will be on working with XSLT. You can use any transformation engine according to your requirements (such as Java or others).

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 10
December 11, 2006
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

A downloadable zip file is available for this article.

In this article, I will be focusing on working with the “xsl:choose” construct available in XSLT.  This article is heavily dependent on the first article of this series, especially when working with ASP.NET 2.0.  If you come across any problems, I strongly suggest you go through my first article.

The entire solution (source code) for this article is available for free download (in the form of a zip).  All the applications in this series have been developed using Microsoft Visual Studio 2005 Professional Edition on Microsoft Windows Server 2003 Standard Edition together with Microsoft SQL Server 2005 Developer Edition as the database.  You can even directly copy and paste the code given in this article and save with extensions XML or XSL and work with your own XSL parsers/engines.

I didn’t really test any of the code in any other tools/IDEs/servers/editions/versions. If you have any problems, please feel free to post in the discussion area.

Setting up your environment

To work with this article, I set up a new database table called “emp” with the fields empno, ename, sal and deptno. I also inserted a few sample rows. Once you execute the following query using “getXMLContent” method:

select Empno,Ename,Sal,Deptno from dbo.emp

You are likely to receive the following XML upon the execution of above SELECT command:

<SQLData>

      <Rows>

            <Empno>1001</Empno>

            <Ename>Jag</Ename>

            <Sal>4400</Sal>

            <Deptno>10</Deptno>

      </Rows>

      <Rows>

            <Empno>1002</Empno>

            <Ename>Chat</Ename>

            <Sal>2800</Sal>

            <Deptno>20</Deptno>

      </Rows>

      <Rows>

            <Empno>1003</Empno>

            <Ename>Winner</Ename>

            <Sal>3700</Sal>

            <Deptno>10</Deptno>

      </Rows>

      <Rows>

            <Empno>1004</Empno>

            <Ename>Dhan</Ename>

            <Sal>5000</Sal>

            <Deptno>20</Deptno>

      </Rows>

</SQLData>

I also included a sample XSLT which works with the above XML document to test the accuracy of XML generation. The XSLT is as follows:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:template match="/">

                  <xsl:apply-templates select="SQLData/Rows/Ename" />

      </xsl:template>

      <xsl:template match="SQLData/Rows/Ename">

                  <xsl:value-of select="."/>

            <br />

      </xsl:template>

</xsl:stylesheet>

Once the above is executed, you should be given a list of all employee names. I also modified the code in such a way that it clearly lists the transformation. The following is the new code:

Dim xslt As New Xsl.XslCompiledTransform()

    xslt.Load(Server.MapPath("XSLTFile11.xsl"))

    ' Create the writer.

    Dim settings As New XmlWriterSettings()

    settings.Indent = True

    settings.IndentChars = ControlChars.Tab

    settings.ConformanceLevel = ConformanceLevel.Auto

    Dim sw As New IO.StringWriter

    Dim writer As XmlWriter = XmlWriter.Create(sw, settings)

    ' Execute the transformation.

    xslt.Transform(docXML, writer)

    writer.Close()

    Me.Literal1.Text = "<pre>" & Server.HtmlEncode(sw.ToString) & "</pre>"

    sw.Close()

Working with xsl:choose in XSLT: introduction

Now it is time to start “control flow” expressions within XSLT. The first construct I would like to concentrate on is “xsl:choose.”

The construct “xsl:choose” is very similar to the “select case” structure.  You can have any number of conditions using “xsl:when” and finally you can have an “else” part using “xsl:otherwise.”

Let us work with a practical example. I would like to display all the employees along with salaries. I would also like to have salaries displayed in bold if they are above 3500. Now, there exists a condition to work with. Such types of conditions can be dealt with either by “xsl:choose” or “xsl:if” (based on the needs). 

The following is the code which displays all employee details along with salaries in bold, if they are above 3500:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

      <table border="1">

      <xsl:apply-templates select="SQLData/Rows" />

      </table>

</xsl:template>  

     

<xsl:template match="SQLData/Rows">

      <tr>

            <td>

                  <xsl:value-of select="Empno"/>

            </td>

            <td>

                  <xsl:value-of select="Ename"/>

            </td>

            <td>

                  <xsl:apply-templates select="Sal" />

            </td>

            <td>

                  <xsl:value-of select="Deptno"/>

            </td>

      </tr>

</xsl:template>

     

<xsl:template match="Sal">

      <xsl:choose>

            <xsl:when test="text() > '3500'">

                  <b>

                        <xsl:value-of select="."/>

                  </b>

            </xsl:when>

            <xsl:otherwise>

                  <xsl:value-of select="."/>

            </xsl:otherwise>

      </xsl:choose>

</xsl:template>

</xsl:stylesheet>

Once the above is executed you are likely to get the following transformation:

<table border="1">

      <tr>

            <td>1001</td>

            <td>Jag</td>

            <td>

                  <b>4400</b>

            </td>

            <td>10</td>

      </tr>

      <tr>

            <td>1002</td>

            <td>Chat</td>

            <td>2800</td>

            <td>20</td>

      </tr>

.

.

.

</table>

I excluded few of the lines for clarity.  The next section will explain in detail the above XSLT code.

Working with xsl:choose in XSLT: explanation

Let us understand the code step by step.  Let us start with the following:

<xsl:template match="/">

      <table border="1">

      <xsl:apply-templates select="SQLData/Rows" />

      </table>

</xsl:template>

From the above code fragment, you can easily understand that I am emitting a TABLE tag and the content of the TABLE tag is based on the template defined in each and every “SQLData/Rows.”  The template for “SQLData/Rows” is defined as follows:

<xsl:template match="SQLData/Rows">

      <tr>

            <td>

                  <xsl:value-of select="Empno"/>

            </td>

            <td>

                  <xsl:value-of select="Ename"/>

            </td>

            <td>

                  <xsl:apply-templates select="Sal" />

            </td>

            <td>

                  <xsl:value-of select="Deptno"/>

            </td>

      </tr>

</xsl:template>

According to the above, you can understand that I am emitting a TR tag for every “SQLData/Rows.”  Within the TR, I am also emitting a TD tag along with the content available in leaf nodes (like Empno, Ename etc.).  The only exception is the following TD emission:

            <td>

                  <xsl:apply-templates select="Sal" />

            </td>

The above emits a TD tag but the content is based on the template defined separately for the “Sal” node.  The template for the “Sal” node is defined as follows:

<xsl:template match="Sal">

      <xsl:choose>

            <xsl:when test="text() > '3500'">

                  <b>

                        <xsl:value-of select="."/>

                  </b>

            </xsl:when>

            <xsl:otherwise>

                  <xsl:value-of select="."/>

            </xsl:otherwise>

      </xsl:choose>

</xsl:template>

The above template may be necessary as we need to test for a condition on “Sal.” From the above code fragment, you can understand that a single “xsl:choose” can be embedded with any number of conditions using “xsl:when.” The “text()” is nothing but the content of “Sal” (in this case). 

The text gets compared with a value of 3500 and emits the text with bold tags if the condition evaluates to true.  If the condition evaluates to false, “xsl:otherwise” gets executed and it emits only the content (without any bold tags).

Emitting HTML together with CSS using XSLT

In all of the previous examples, I simply emitted HTML.  In fact, you can not only emit HTML; you can also emit CSS based on your needs!

Let us modify the business need specified in the previous section.  Now, I would like to have all the employee details listed with the salaries in red, if earnings are more than 3500. The following is the modified XSLT which accomplishes the same:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

      <table border="1">

      <xsl:apply-templates select="SQLData/Rows" />

      </table>

</xsl:template>  

     

<xsl:template match="SQLData/Rows">

      <tr>

            <td>

                  <xsl:value-of select="Empno"/>

            </td>

            <td>

                  <xsl:value-of select="Ename"/>

            </td>

            <xsl:apply-templates select="Sal" />

            <td>

                  <xsl:value-of select="Deptno"/>

            </td>

      </tr>

</xsl:template>

     

<xsl:template match="Sal">

      <xsl:choose>

            <xsl:when test="text() > '3500'">

                  <td style="color: red">

                        <xsl:value-of select="."/>

                  </td>

            </xsl:when>

            <xsl:otherwise>

                  <td>

                        <xsl:value-of select="."/>

                  </td>

            </xsl:otherwise>

      </xsl:choose>

</xsl:template>

</xsl:stylesheet>

When the above code gets executed, you are likely to get the following transformation:

<table border="1">

      <tr>

            <td>1001</td>

            <td>Jag</td>

            <td style="color: red">4400</td>

            <td>10</td>

      </tr>

      <tr>

            <td>1002</td>

            <td>Chat</td>

            <td>2800</td>

            <td>20</td>

      </tr>

.

.

.

</table>

The only trick I used from all of the above code is that I emitted the TD tag of “Sal” within its own template, together with CSS wherever appropriate!

Working with multiple xsl:when within xsl:choose in XSLT

In the previous sections, we dealt with only one single “xsl:when” within “xsl:choose.”  Now, let us work with multiple “xsl:when” statements.

Let us again modify the business need specified in the previous section.  Now, I would like to have all the employee details listed with:

  • salary in red, if earnings are more than 4000.
  • salary in blue, if earnings are more than 3000 and less than 4000.

The following is the entire XSLT which accomplishes the same:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

      <table border="1">

      <xsl:apply-templates select="SQLData/Rows" />

      </table>

</xsl:template>  

     

<xsl:template match="SQLData/Rows">

      <tr>

            <td>

                  <xsl:value-of select="Empno"/>

            </td>

            <td>

                  <xsl:value-of select="Ename"/>

            </td>

            <xsl:apply-templates select="Sal" />

            <td>

                  <xsl:value-of select="Deptno"/>

            </td>

      </tr>

</xsl:template>

     

<xsl:template match="Sal">

      <xsl:choose>

            <xsl:when test="text() > '4000'">

                  <td style="color: red">

                        <xsl:value-of select="."/>

                  </td>

            </xsl:when>

            <xsl:when test="text() > '3000'">

                  <td style="color: blue">

                        <xsl:value-of select="."/>

                  </td>

            </xsl:when>

            <xsl:otherwise>

                  <td>

                        <xsl:value-of select="."/>

                  </td>

            </xsl:otherwise>

      </xsl:choose>

</xsl:template>

</xsl:stylesheet>

When the above code gets executed, you are likely to get the following transformation:

<table border="1">

      <tr>

            <td>1001</td>

            <td>Jag</td>

            <td style="color: red">4400</td>

            <td>10</td>

      </tr>

      <tr>

            <td>1002</td>

            <td>Chat</td>

            <td>2800</td>

            <td>20</td>

      </tr>

      <tr>

            <td>1003</td>

            <td>Winner</td>

            <td style="color: blue">3700</td>

            <td>10</td>

      </tr>

      <tr>

            <td>1004</td>

            <td>Dhan</td>

            <td style="color: red">5000</td>

            <td>20</td>

      </tr>

</table>

More conditions within xsl:when

It is recommended to use XML entity references within conditions, for better compatibility and bug-free compilation. In the following example, I am trying to have more than one condition within “xsl:when” and using entity references as conditional operators:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

      <table border="1">

      <xsl:apply-templates select="SQLData/Rows" />

      </table>

</xsl:template>  

     

<xsl:template match="SQLData/Rows">

      <tr>

            <td>

                  <xsl:value-of select="Empno"/>

            </td>

            <td>

                  <xsl:value-of select="Ename"/>

            </td>

            <xsl:apply-templates select="Sal" />

            <td>

                  <xsl:value-of select="Deptno"/>

            </td>

      </tr>

</xsl:template>

     

<xsl:template match="Sal">

      <xsl:choose>

            <xsl:when test="text() &gt; '3000' and text() &lt; '4000'">

                  <td style="color: red">

                        <xsl:value-of select="."/>

                  </td>

            </xsl:when>

            <xsl:otherwise>

                  <td>

                        <xsl:value-of select="."/>

                  </td>

            </xsl:otherwise>

      </xsl:choose>

</xsl:template>

</xsl:stylesheet>

Within the above code “&gt;” stands for “>” and “&lt;” stands for “<”.  Sometimes, you may also have to use “&quot;” instead of a single quote!  So, keep in mind that XML entity references play major role in XSLT.

I hope you enjoyed the article and any comments, suggestions, feedback, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 11 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials