Create a menu of any depth recursively with XHTML Horizontal List items.
Using (X)HTML, CSS, XML, XSLT, JSP, JSTL
Updated: 6:31 p.m. EDT, February 29th, 2008 - rashmiru
Objective:
Create a menu of any depth recursively with XHTML Horizontal List items.
Steps to create the nested menu recursively:
-
Create a mock-up of horizontal dropdowns to get an idea of how the end result should look like.
References:- A List Apart - Horizontal Dropdowns
- Suckerfish Dropdowns
- Horizontal Lists - Tutorial
- Pure CSS Hover List
- Define the menu's data as an XML structure, so that the XML nodes can be processed recursively.
- Create the XSLT to transform the XML structure to the nested HTML lists recursively.
- Write the JSP 2.1 with JSTL 1.2, use the JSTL XML transform tag and transform the XML with the XSLT to generate the resulting output.
- Finally use CSS inline property on the nested (X)HTML list to represent it as either horizontal drop-downs, or tabbed menus.
1) The end result in (X)HTML format should look something like this sample:
sample output
<ul>
<li>Main Menu 1
<ul>
<li>Sub Menu Level 1
<ul>
<li>Sub Menu Level 2
<ul>
<li>Sub Menu Level 3
<ul>
<li>Sub Menu Level n</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Main Menu 2
<ul>
<li>Fishes
<ul>
<li>Razor Fish</li>
<li>Cat Fish</li>
<li>Salmon</li>
<li>Tuna</li>
</ul>
</li>
</ul>
</li>
</ul>
Download Sample Output.
The above renders into the following hierarchy:
- Main Menu 1
- Sub Menu Level 1
- Sub Menu Level 2
- Sub Menu Level 3
- Sub Menu Level n
- Sub Menu Level 3
- Sub Menu Level 2
- Sub Menu Level 1
- Main Menu 2
- Fishes
- Razor Fish
- Cat Fish
- Salmon
- Tuna
- Fishes
2) Representing the Menu in XML. Following is the menu hierarcy represented with a custom XML data structure:
menu_items.xml
<?xml version="1.0" encoding="UTF-8"?> <item> <item> <name>Main Menu 1</name> <item> <name>Sub Menu Level 1</name> <item> <name>Sub Menu Level 2</name> <item> <name>Sub Menu Level 3</name> <item> <name>Sub Menu Level n</name> </item> </item> </item> </item> </item> <item> <name>Main Menu 2</name> <item> <name>Fishes</name> <item> <name>Razor Fish</name> </item> <item> <name>Cat Fish</name> </item> <item> <name>Salmon</name> </item> <item> <name>Tuna</name> </item> </item> </item> </item>
Download menu_items.xml.
If you want it to be easier to identify the menu level, the you can add a level attribute to each
item node or name node and then set the level number corresponding to each menu item.
3) Recursively transforming the XML with XSLT 1.0
Use the following XSLT to recursively transform the XML to XHTML nested lists.
transform_menu_recursively.xsl
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" omit-xml-declaration="yes" /> <xsl:template match="item"> <ul> <li> <xsl:value-of select="name" /> </li> <xsl:apply-templates select="item" /> </ul> </xsl:template> </xsl:stylesheet>
Download transform_menu_recursively.xsl
4) In the JSP, make use of JSTL's XML tag and transform the XML with the XSLT.
Optionally write the html in XHTML format so that the codes cross-browser compatibility is maximized.
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %> <html> <head><title>Sample - Print Items Recursively in a HTML List</title></head> <body> <c:import url="menu_items.xml" var="xml"/> <c:import url="transform_menu_recursively.xsl" var="xsl"/> <x:transform doc="${xml}" xslt="${xsl}"/> </body> </html>
Download index.jsp
5) Use CSS to style the list in any format.
HTML lists are rendered vertically by default, this vertical display can
be changed to a horizontal display by using the CSS inline property on the HTML list.
See the output of the transformation here...
This recursive menu tutorial was tested with:
- JavaSE 5 / 6
- Tomcat 5.5 / 6.x
- Servlet 2.4 / 2.5 (comes with Tomcat no separate download required).
- JSTL 1.1 / 1.2
- Xalan 2.7 (included with JSTL 1.2)
- XML 1.0
- XSLT/XPath 1.0
- CSS 2.0
- XHTML 1.0
Books: