|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThis article will demonstrate a simple and generic way to use XSLT to generate a multi-level HTML tree menu from an XML source. JScript is used for expanding and contracting the menu entries. (This requires a minimum of Internet Explorer 5. I have not tested this on any other browsers.) The XML SourceThis is a subset of the source XML (full XML source is in the zip file). <menu>
<entry>
<text>In-House</text>
<url>InHouse.htm</url>
<entry>
<text>Web Development</text>
<url>WebDev.htm</url>
</entry>
</entry>
</menu>
The XSLTFor each menu entry, the XSLT processes it, then drills down until it has processed that entry's last child. <?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="//menu/entry">
<xsl:call-template name="SubMenu">
<xsl:with-param name="strCSS">Parent IsVisible</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="SubMenu">
<xsl:param name="strCSS" />
<xsl:variable name="strURL" select="url" />
<div class="{$strCSS}">
<xsl:choose>
<xsl:when test="count(entry) > 0">
<!-- Element has children, it can be expanded -->
<input type="hidden" id="hidIsExpanded" value="0" />
<label id="lblExpand" class="Expander" onclick="ExpanderClicked()">+
</label>
</xsl:when>
<xsl:otherwise>
<label class="Expander"> </label>
</xsl:otherwise>
</xsl:choose>
<a href="{$strURL}"><xsl:value-of select="text" /></a>
<xsl:for-each select="entry">
<xsl:call-template name="SubMenu">
<xsl:with-param name="strCSS">NotVisible</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
Transforming the XML on the serverASP is used to perform server-side transformation of the XML. <%
dim xmlMenu
dim xslMenu
'Get the source XML
set xmlMenu = server.CreateObject("Microsoft.XMLDOM")
xmlMenu.async = false
xmlMenu.load server.MapPath("TreeFromXMLUsingXSLT.xml")
'Get the XSLT to transform the XML
set xslMenu = server.CreateObject("Microsoft.XMLDOM")
xslMenu.async = false
xslMenu.load server.MapPath("TreeFromXMLUsingXSLT.xsl")
'Transform the source XML using XSLT
Response.Write xmlMenu.transformNode(xslMenu)
set xmlMenu = nothing
set xslMenu = nothing
%>
Controlling the menu entriesClient-side JScript is used to first determine whether a menu entry has been expanded or collapsed, and then adjusts the selected menu entry's style settings. <script language="jscript"> function ExpanderClicked() { //Get the element that was clicked var ctlExpander = event.srcElement; var ctlSelectedEntry = ctlExpander.parentElement; //Get all the DIV elements that are direct descendants var colChild = ctlSelectedEntry.children.tags("DIV"); if(colChild.length > 0) { var strCSS; //Get the hidden element that //indicates whether or not entry is expanded var ctlHidden = ctlSelectedEntry.all("hidIsExpanded"); if(ctlHidden.value == "1") { //Entry was expanded and is being contracted ctlExpander.innerHTML = "+ "; ctlHidden.value = "0"; strCSS = "NotVisible"; } else { //Entry is being expanded ctlExpander.innerHTML = "- "; ctlHidden.value = "1"; strCSS = "IsVisible"; } //Show all the DIV elements that are direct children for(var intCounter = 0; intCounter < colChild.length; intCounter++) { colChild[intCounter].className = strCSS; } } } </script> Style settingCSS settings are used to specify if a menu entry should be visible or hidden.
The body
{
font-family: Verdana;
font-size: x-small;
}
.IsVisible
{
display: block;
}
.NotVisible
{
display: none;
}
.Expander
{
cursor: hand;
font-family: Courier;
}
.Parent DIV
{
margin-Left: 15px !important;
}
The last setting ( Using images instead of + and -It is fairly simple to show images instead of a "+" and "-" next to each
entry. To do this, alter the XSLT and replace the
| ||||||||||||||||||||