We will create an XSL document (Menu.xsl) containing the
code to navigate through the XML document (using XPath) already created in the
above step, read the element values, and apply the necessary formats.
First of all, we will read the main nodes without their
corresponding child element and then for each main node we will place the
children elements in a DIV Layer just beneath its position. By default, the
entire sub children elements will be hidden and we will show them only when
they are requested using JavaScript
Below is the XSL document which will be explained step by
step later on in this article.
Listing 2
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:asp="http://www.microsoft.com">
<xsl:output method="html" indent="yes" encoding="iso-8859-1"/>
<xsl:template match="MenuItems/*">
<xsl:variable name="NodeName">
<xsl:value-of select="name(current())"/>
</xsl:variable>
/xsl:template>
</xsl:stylesheet>
The code in bold will create a variable that holds the name
of the root element children without its sub children elements (Item1, Item2,
Item3).
Listing 3
<xsl:variable name=”NodeName”></xsl:variable>
In the above line of code we are defining a variable with a
name “NodeName” so that we can reference it later when it is needed.
Listing 4
<xsl:value–of select=”name(current())”></xsl:variable>
The above statement will store the name of the current node
in the variable.
Now, we will create one table containing the nodes’ name in
the NodeName variable. We will display each node name in a row. The code in
bold in the listening below will demonstrate how to do this task.
To get the values in a variable you have to add the "$"
sign before variable name.
Listing 5
<html>
<body>
<table border="1" width="150px" >
<tr>
<td align="Center"><xsl:value-of select="$NodeName"/></td>
</tr>
</table>
</body>
</html>
Figure 1: Table holding main menu items

The above figure shows the table with four rows containing
the values of the variable.
Now we will create for each node a table containing its
children element. We will insert this table inside a div layer which will be
hidden by default.
Listing 6
<div style="OVERFLOW:AUTO; width=150px;height=100px; display:none" runat="server" id="{$NodeName}" >
<xsl:for-each select="node()">
<table>
<xsl:variable name="ChildNodeName">
<xsl:value-of select="./child::node()"/>
</xsl:variable>
<td width="150px" align="center"><xsl:value-of select="$ChildNodeName"/></td>
</table>
</xsl:for-each>
</div>
The code in bold will loop through each node in the XML
document, store its child elements inside a new variable named
"ChildNodeName" and display each element in a row of the second
table.
Listing 7
<xsl:value-of select="./child::node()"/>
The above statement uses XPath (./child::node()) whose
purpose is to get the child nodes of a specific node.
Note, for each div layer we are assigning a different id;
this id will be the same as the node name.
After completing the above steps, we have to integrate
JavaScript to show or hide the div layer containing the children elements when
the user clicks on a specified node.
Listing 8
<script lang="javascript" type="text/javascript" >
function HideShowDiv(divid)
{
var divlayer = document.getElementById(divid);
if(divlayer.style.display == "block")
{
divlayer.style.display = "none";
}
else
divlayer.style.display = "block"
}
function ChangeBg(tdid)
{
var td = document.getElementById(tdid);
td.style.background = "#3399ff";
td.style.color= "white";
}
function ReturnBg(tdid)
{
var td = document.getElementById(tdid);
td.style.background = "white";
td.style.color = "black";
}
</script>
The HideShowDiv(divid) function
checks whether the div layer is hidden and shows it and vice versa. It accepts
as parameter the div layer id which stored in the NodeName variable.
The ChangeBg(tdid) function will
change the background and text color onmouseover event of the <td> in the
second table.
The ReturnBg(tdid) function will
bring the background and text color back to their original values onmouseleave
event.
Those functions take as parameter the id which will always
be stored in the ChildNodeName variable.
Modify the <td> tag of the second table to look like
the same as the code below.
Listing 9
<td onmouseover="ChangeBg('{$ChildNodeName}')" id="{$ChildNodeName}"
onmouseleave="ReturnBg('{$ChildNodeName}')" width="150px"
align="center"><xsl:value-of select="$ChildNodeName"/></td>
This is how the XSL Document should look:
Listing 10
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:asp="http://www.microsoft.com">
<xsl:output method="html" indent="yes" encoding="iso-8859-1"/>
<xsl:template match="MenuItems/*">
<xsl:variable name="NodeName">
<xsl:value-of select="name(current())"/>
</xsl:variable>
<html>
<head>
<script lang="javascript" type="text/javascript" >
function HideShowDiv(divid)
{
var divlayer = document.getElementById(divid);
if(divlayer.style.display == "block")
{
divlayer.style.display = "none";
}
else
divlayer.style.display = "block"
}
function ChangeBg(tdid)
{
var td = document.getElementById(tdid);
td.style.background = "#3399ff";
td.style.color= "white";
}
function ReturnBg(tdid)
{
var td = document.getElementById(tdid);
td.style.background = "white";
td.style.color = "black";
}
</script>
</head>
<body>
<table border="1" width="150px" >
<tr>
<td onmousedown="HideShowDiv('{$NodeName}')" align="Center"><xsl:value-of select="$NodeName"/></td>
</tr>
</table>
<div style="OVERFLOW:AUTO; width=150px;height=100px; display:none" runat="server" id="{$NodeName}" >
<xsl:for-each select="node()">
<table>
<xsl:variable name="ChildNodeName">
<xsl:value-of select="./child::node()"/>
</xsl:variable>
<td onmouseover="ChangeBg('{$ChildNodeName}')"
id="{$ChildNodeName}" onmouseleave="ReturnBg('{$ChildNodeName}')"
width="150px" align="center"><xsl:value-of select="$ChildNodeName"/></td>
</table>
</xsl:for-each>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code Behind
You have two ways to achieve the transformation.
A. By adding code to the code behind page
Include the namespaces below to be able to use the classes
for XML and XSL:
Listing 11
using System.Xml;
using System.Xml.Xsl;
The code below will create an instance of the XmlDocument
class and load the already created XML document, create an instance of the
XslTransform class, load the already created XSL document and use the
XmlTextWriter class to write the output into HTML.
Use the Transform method of the XslTransform class to make
the transformation.
Add to the Page_Load event the code below:
Listing 12
// Create an instance of the XmlDocument class and load the xml file already created
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(Server.MapPath("./Menu.xml"));
// Create an instance of the XslTranform class and load the xsl file already created
XslTransform xslTran = new XslTransform();
xslTran.Load(Server.MapPath("./Menu.Xsl"));
// Write the transformation into a new html
XmlTextWriter htmlWriter =
new XmlTextWriter(Server.MapPath("./output.html"),
System.Text.Encoding.UTF8);
htmlWriter.Close();
// the XslTransform class contains a method Transform to transform the xml into html.
xslTran.Transform(xmlDoc, null, Response.OutputStream);
B. By using XML server control
If you want to use the XML server control without adding
code to the page behind, drag and drop the XML server control from the toolbox
under the WebForms tab, Right click it and select properties, click on the
DocumentSource and add the XML document, click on the TransformSource and add
the XSL file then run your project.
Below is a snapshot of what your menu will look like after
completing all the stages mentioned above.
Figure 2: Shows the child elements of the first
node in the XML document

To customize your menu, just modify the XML file elements
and run the project.