How to use XSLT with TreeView to make XML hierarchical data binding in ASP.NET

In the article How to use TreeView to make XML hierarchical data binding in ASP.NET is shown how you can use XmlDataSource and TreeView control together to make hierarchical data binding. In addition XmlDataSource has built-in support for XSL transformations. You can use it to convert the source XML document into an XML structure that’s easier to data bind. For example, you can generate an XML document with the results you want and generate a structure with elements converted into attributes for easier data binding.

You can specify a stylesheet, by setting the XmlDataSource.TransformFile to point to a file with the XSL transform, or you can supply the stylesheet as a single long string using the XmlDataSource.Transform property. You can use both stylesheets and XPath expressions, but the stylesheet is always applied first.

 

<asp:XmlDataSource ID=”sourceAlbums” runat=”server” DataFile=”AlbumsList.xml” TransformFile=”AlbumsList.xsl”>

</asp:XmlDataSource>

 

One good reason to use the XSLT features of the XmlDataSource is to get your XML data ready for display in a hierarchical control such as the TreeView. For example, imagine you want to create a list of hits grouped by albume. You also want to put all the content into attributes so it’s easy to bind.

 

Here’s the final XML you’d like:

 

<Albums>

<Album ID=”1″ Title=”Thriller”>

<Hit Name=”Thriller” />

<Hit Name=”The Girl Is Mine” />

<Hit Name=”Billie Jean” />

</Album>

<Album ID=”2″ Title=”Back in Black”>

<Hit Name=”Hells Bells” />

<Hit Name=”Shoot to Thrill” />

<Hit Name=”You Shook Me All Night Long” />

</Album>

</Albums>

 

The XML used to illustrate the idea is the following:

 

<?xml version=”1.0″ encoding=”utf-8″?>

<AlbumsList>

<Album ID=”1″ Title=”Thriller”>

<Artist>

Michael Jackson

</Artist>

<Released>

1982

</Released>

<Genre>

Pop/Rock/R and B

</Genre>

<Hits>

<Hit>Thriller</Hit>

<Hit>The Girl Is Mine</Hit>

<Hit>Billie Jean</Hit>

</Hits>

</Album>

<Album ID=”2″ Title=”Back in Black”>

<Artist>

AC/DC

</Artist>

<Released>

1980

</Released>

<Genre>

Hard rock/Heavy metal

</Genre>

<Hits>

<Hit>Hells Bells</Hit>

<Hit>Shoot to Thrill</Hit>

<Hit>You Shook Me All Night Long</Hit>

</Hits>

</Album>

<Album ID=”3″ Title=”The Dark Side of the Moon” >

<Artist>

Pink Floyd

</Artist>

<Released>

1973

</Released>

<Genre>

Progressive rock

</Genre>

<Hits>

<Hit>Money</Hit>

<Hit>Time</Hit>

</Hits>

</Album>

</AlbumsList>

 

You can transformed into targeted markup by using the following, more advances XLS stylesheet. It extracts every <Album> element from the source document and creates a slightly rearranged  <Album> element for it in the result document. The new <Album> element uses attributes to expose the ID and title information (rather than using nested elements). The transformed <Album> element also includes nested <Hit> elements, but they’re also modified. Now, each <Hit> element exposes the hit      name as an attribute (rather than using text content).

 

<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” version=”1.0″>

<xsl:output method=”xml”/>

<xsl:template match=”/”>

<!– Rename the root element. –>

<xsl:element name=”Albums”>

<xsl:apply-templates select=”AlbumsList/Album” />

</xsl:element>

</xsl:template>

<xsl:template match=”Album”>

<!– Transform the <Album> element into a new <Album> element

with a different structure. –>

<xsl:element name=”Album”>

<!– Keep the ID attribute. –>

<xsl:attribute name=”ID”>

<xsl:value-of select=”@ID”/>

</xsl:attribute>

<!– Put the nested <Title> text into an attribute. –>

<xsl:attribute name=”Title”>

<xsl:value-of select=”@Title”/>

</xsl:attribute>

<xsl:apply-templates select=”Hits/Hit” />

</xsl:element>

</xsl:template>

<xsl:template match=”Hit”>

<xsl:element name=”Hit”>

<!– Put the nested <Hit> text into an attribute. –>

<xsl:attribute name=”Name”>

<xsl:value-of select=”text()”/>

</xsl:attribute>

</xsl:element>

</xsl:template>

</xsl:stylesheet>

 

Now you can bind this to the TreeView and display it with this set of bindings:

 

<body>

<form id=”form1″ runat=”server”>

<div>

<asp:XmlDataSource ID=”sourceAlbums” runat=”server” DataFile=”AlbumsList.xml” TransformFile=”AlbumsList.xsl”>

</asp:XmlDataSource>

<asp:TreeView ID=”TreeView1″ runat=”server” DataSourceID=”sourceAlbums” AutoGenerateDataBindings=”False”>

<DataBindings>

<asp:TreeNodeBinding DataMember=”Albums” Text=”Albums” />

<asp:TreeNodeBinding DataMember=”Album” TextField=”Title” />

<asp:TreeNodeBinding DataMember=”Hit” TextField=”Name” />

</DataBindings>

</asp:TreeView>

</div>

</form>

</body>

 

The next picture shows the final result:

 

Using of XSLT with TreeView control to make XML hierarchical data binding

Using of XSLT with TreeView control to make XML hierarchical data binding