Developing XSLT-based Applications in ASP.NET 2.0

This is the first article in a series focused on developing XSLT-oriented applications using ASP.NET 2.0. Even though the title includes 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: 4 stars4 stars4 stars4 stars4 stars / 23
December 04, 2006
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

A downloadable zip file is available for this article.

The entire solution (source code) for this article is available as a free download in the form of a zip file.  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. I didn’t really test any of the code in any of the other  tools/IDEs/servers/editions/versions.  If you have any problems, please feel free to post in the discussion area.

How to transform XML to XSLT using ASP.NET 2.0

Transforming XML to XSLT using ASP.NET 2.0 is quite easy. Working with the XML control (available in the toolbox) makes it easy to transform any XML document to the specified XSLT.

As it is a bit tedious to always author XML documents, I simply converted the output of a result set (or dataset) to an XML document by using the following method:

Private Function getXMLContent(ByVal SQL As String) As XmlDocument

    Dim ds As New DataSet("SQLData")

    Dim da As New SqlDataAdapter(SQL, "data source=laptop2k3sql2k5;initial catalog=AdventureWorks;user id=sa;password=eXpress2005")

    da.Fill(ds, "Rows")

    da.Dispose()

    Dim sw As New System.IO.StringWriter

    ds.WriteXml(sw)

    ds.Dispose()

    Dim docXML As New XmlDocument

    docXML.LoadXml(sw.ToString())

    sw.Close()

    Return docXML

  End Function

The above method accepts a SELECT query and returns XML in the form of an object of type “XmlDocument.” You may need to modify the above method to suit your production requirements.

Now, let us see how to transform the XML document to the specified XSLT.  The following is the code used to achieve the same:

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim docXML As XmlDocument = getXMLContent("select EmployeeID, FirstName, JobTitle from HumanResources.vEmployee")

    Me.txtXML.Text = docXML.InnerXml

    Dim xp As New XPath.XPathDocument(New XmlTextReader(New IO.StringReader(docXML.InnerXml)))

    Xml1.XPathNavigator = xp.CreateNavigator

    Xml1.TransformSource = Server.MapPath("XSLTFile01.xsl")

  End Sub

To work with the above code, you need to drag and drop an XML control from the toolbox onto the web page.  You may have to modify the name of the XSLT file according to your design or theme.

Testing XSLT using ASP.NET 2.0

When the button is clicked (as given in previous section), it generates an XML document (from the database), which is similar to the following hierarchy:

<SQLData>

      <Rows>

            <EmployeeID>1</EmployeeID>

            <FirstName>Guy</FirstName>

            <JobTitle>Production Technician - WC60</JobTitle>

      </Rows>

      <Rows>

            <EmployeeID>2</EmployeeID>

            <FirstName>Kevin</FirstName>

            <JobTitle>Marketing Assistant</JobTitle>

      </Rows>

.

.

.

</SQLData>

The following is the first sample XSLT to test:

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

<xsl:stylesheet version="1.0"

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

<xsl:template match="/">

      <b>

                  <xsl:value-of select="SQLData/Rows/FirstName"/>

      </b>

</xsl:template>

</xsl:stylesheet>  

When the XML document gets transformed based on the above XSLT, it displays the “FirstName” of the first employee in bold.  The result of the above transformation would be similar to the following:

      <b>

                  Guy

      </b>

The first and the most important construct is the following:

<xsl:template match="/">

.

.    

</xsl:template>

Any construct starting with “xsl:template” is called a “template.” The template is a blueprint for transformation. In the above case, it checks whether the current “context” is at “root” or not.  If the “context” is at root, the template available within the construct is applied.

The following is the body of above template:

<b>

      <xsl:value-of select="SQLData/Rows/FirstName"/>

</b>

The above transforms the first value (or text) available in “SQLData/Rows/FirstName” to display as bold.

Separating templates from the root template

Let us consider the following XSLT:

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

<xsl:stylesheet version="1.0"

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

<xsl:template match="FirstName">

      <b>

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

      </b>

</xsl:template>

</xsl:stylesheet>

The above XSL simply transforms only the text available in the “FirstName” tag (at any location in the document).  All the rest would be directly displayed without any transformation.

If you wanted to handle the “FirstName” separately from root, you can rewrite the above XSLT 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 />

</xsl:template>  

     

<xsl:template match="FirstName">

      <b>

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

      </b>

</xsl:template>

</xsl:stylesheet>

The above includes both root and “FirstName” templates.  According to the above XSLT, when it finds “FirstName,” it goes to the template defined outside the root template.

If you forget to provide the following statement:

            <xsl:apply-templates />

it would be a blank template and nothing would get displayed (or transformed).

Defining templates for particular tags

In the previous section, we observed that we can include any number of templates according to our requirements.  Now, let us consider how we would extract only the “FirstName” (without any other data) and transform it using the template. The following code handles this task:

<?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/FirstName" />

</xsl:template>  

     

<xsl:template match="FirstName">

      <b>

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

      </b>

      <br />

</xsl:template>

</xsl:stylesheet>

You need to observe only the following statement from the above XSLT:

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

That statement particularly says that it needs to apply a separate template (if available) if it finds “FirstName” at the path “SQLData/Rows.”

In the above case, it searches for “FirstName” only at the path “SQLData/Rows.”  Let us consider defining and applying a template for “FirstName” available at any path. You may need to modify the above code to the following to achieve 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="/">

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

</xsl:template>  

     

<xsl:template match="FirstName">

      <b>

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

      </b>

      <br />

</xsl:template>

</xsl:stylesheet>

When you precede the path with “//” it reflects to “any path.”

Working with all siblings available at a particular path

Let us now consider working with more than one tag at a time (belonging to the same row or siblings).  The following code sample achieves 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="/">

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

</xsl:template>  

     

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

      <xsl:value-of select="EmployeeID"/>,

      <b>

            <xsl:value-of select="FirstName"/>,

      </b>

      <br />

</xsl:template>

</xsl:stylesheet>

From the above you can understand that I defined a new template for “SQLData/Rows.” Within that template, I am extracting “EmployeeID” and “FirstName” and transforming them according to our needs.

Let us now further extend the above XSLT to have sibling level and tag level templates as shown in the following:

<?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" />

</xsl:template>  

     

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

      <xsl:value-of select="EmployeeID"/>,

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

      <br />

</xsl:template>

<xsl:template match="FirstName">

            <b>

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

            </b>

</xsl:template>

</xsl:stylesheet>

As you can see, you can define and work with any number of templates at various levels according to your needs.

Transforming XML data to HTML tables using XSLT

Since we are now a bit more familiar with templates, let us go for a practical example. I would like to display employee information in the form of an HTML table (by using only templates). The following code achieves 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="EmployeeID"/>   </td>

            <td><xsl:apply-templates select="FirstName" /></td>

      </tr>

</xsl:template>

<xsl:template match="FirstName">

            <b>

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

            </b>

</xsl:template>

</xsl:stylesheet>

In the root tag, I am simply emitting a TABLE tag. In the “Rows” template, I am emitting TR and TD tags. The TD tags will be filled with the values extracted using “xsl:value-of.”

Is there any possibility of achieving this without using templates at all? Yes. You can still do it. Go through the following example:

<?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 width="50%" cellspacing="0" cellpadding="0" style="font-
family:verdana;font-size:X-Small
" border="1">

                  <tr bgcolor="#336699">

                        <th align="left">

                              <font color="White">EmployeeID</font>

                        </th>

                        <th align="right">

                              <font color="White">FirstName</font>

                        </th>

                  </tr>

                  <xsl:for-each select="SQLData/Rows">

                        <tr>

                              <td align="left">

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

                              </td>

                              <td align="right">

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

                              </td>

                        </tr>

                  </xsl:for-each>

            </table>

</xsl:template>

</xsl:stylesheet>

The above is only for your understanding. My upcoming articles will explain these new concepts in a detailed fashion.

Parsing through previous and next siblings using XSLT

Let us consider the following XSLT:

<?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/FirstName" />

</xsl:template>  

     

<xsl:template match="FirstName">

      <b>

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

      </b>

      <br />     

</xsl:template>

</xsl:stylesheet>

From the above you can understand that it displays all “FirstName” related information in bold. What if I want to display the “EmployeeID” along with the “FirstName?” In the above path, I didn’t specify “EmployeeID” at all and the template simply belongs to “FirstName.” 

Now within the “FirstName” template, I would like to access the “EmployeeID.” It is the previous tag at the same level (or it is simply a preceding sibling). The following will help you understand how to access previous and next siblings:

<?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/FirstName" />

      </xsl:template>

      <xsl:template match="FirstName">

            <xsl:value-of select="./preceding::EmployeeID[1]"/> -

            <b>

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

            </b> -

            <xsl:value-of select="./following::JobTitle[1]"/>,

            <br />

      </xsl:template>

</xsl:stylesheet>

The power of using XSLT solely depends on your grasp of XPath. I strongly suggest you to learn XPath before you learn XSLT.  You can also find different utilities on this web site for learning XPath. Good luck.

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 1 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials