Forum Moderators: open
I'm trying to build a css menu with up to 3 levels that uses an xml file and an xsl stylesheet to transform it.
However I know next to nothing about xsl and from what I've read at w3schools this looks like it could get really complicated.
Normally I would do this server side but unfortunately in this case that isn't an option.
Any help would be much appreciated :)
Here is the xsl stylesheet so far (not working)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/><xsl:template match="/">
<ul id="navmenu">
<ul>
<xsl:for-each select="catalog/cd">
<li><a <xsl:attribute name="href"><xsl:value-of select="artist"/></xsl:attribute>><xsl:value-of select="title"/></a></li>
</xsl:for-each>
</ul>
</ul>
<!-- -->
</xsl:template>
</xsl:stylesheet>
The xml datasource is from w3Schools and can be found at [w3schools.com ]
Here is the relevant html page with menu css
<style type="text/css">body{font-family: Tahoma,Verdana, Geneva, Arial, Helvetica, sans-serif;color: 000;background-color: #fff; font-size:75%;margin:0 auto;padding:0 auto; line-height: 16px;}
#shell{height:100%;}
#header{background-color: #000;height: 21;margin:auto 0;padding:auto 0;}
#nav{margin:1px 0px 0px 0px;background-image: url(images/headliqui.gif);background-repeat: repeat-x;}
.spacer{width:167px;}
#content{margin:2px 0px 0px 10px;height:83%;width:100%;}
#products{float:left;height:100%;}
#creation{background-color:#F8F8F8;float:left;margin:0;padding:0px 5px 0px 0px;height:100%;width: 169px;}
a.box{background-color:#F0F0EE;width:160px;height:23px;font-size:11px;text-align:left;margin:3px;padding:5px 5px 5px 20px;color:000;text-decoration:none;}
a.box:hover{background-color:#FFBE5D;color:#000;width:160px;height:23px;margin:3px;padding:5px 5px 5px 20px;}
a.img{border:0px;}
#info{float:left;margin:5px;height:97%}
#footer{background-color: #79799F;}
/* MENU Root = Horizontal, Secondary = Vertical */
ul#navmenu {
margin: 0;
padding: 0;
border: 0 none;
width: 926px; /*For KHTML*/
list-style: none;
height: 48px;
background-image: url(images/Navigation.gif);
background-repeat: no-repeat;
}
ul#navmenu li {
margin: 0;
border: 0 none;
padding: 0;
float: left; /*For Gecko*/
display: inline;
list-style: none;
position: relative;
height: 27px;
text-align: left;
}
ul#navmenu ul {
margin: 0;
border: 0 none;
padding: 0;
width: 130px;
list-style: none;
display: none;
position: absolute;
top: 36px;
left: 13;
}
ul#navmenu ul:after /*From IE 7 lack of compliance*/{
clear: both;
display: block;
font: 1px/0px serif;
content: ".";
height: 0;
visibility: hidden;
}
ul#navmenu ul li {
width: 150px;
float: left; /*For IE 7 lack of compliance*/
display: block !important;
display: inline; /*For IE*/
top: 10px;
}
/* Root Menu */
ul#navmenu a {
padding: 0;
float: none !important; /*For Opera*/
float: left; /*For IE*/
display: block;
color: #ffffff;
font: normal 12px Arial;
text-decoration: none;
height: auto !important;
height: 1%; /*For IE*/
}
/* Root Menu Hover Persistence */
ul#navmenu a:hover,
ul#navmenu li:hover a,
ul#navmenu li.iehover a {
color: #CCCCCC;
}
/* 2nd Menu */
ul#navmenu li:hover li a,
ul#navmenu li.iehover li a {
float: none;
background: #B5BACE;
color: #ffffff;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
height: 23px;
width: 150px;
padding: 6px;
}
/* 2nd Menu Hover Persistence */
ul#navmenu li:hover li a:hover,
ul#navmenu li:hover li:hover a,
ul#navmenu li.iehover li a:hover,
ul#navmenu li.iehover li.iehover a {
background: #A6ACC3;
color: #ffffff;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
height: 23px;
width: 150px;
padding: 6px;
}
/* 3rd Menu */
ul#navmenu li:hover li:hover li a,
ul#navmenu li.iehover li.iehover li a {
float: none;
background: #999EBB;
color: #ffffff;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
height: 23px;
width: 150px;
padding: 6px;
}
/* 3rd Menu Hover Persistence */
ul#navmenu li:hover li:hover li a:hover,
ul#navmenu li:hover li:hover li:hover a,
ul#navmenu li.iehover li.iehover li a:hover,
ul#navmenu li.iehover li.iehover li.iehover a {
background: #999EBB;
color: #ffffff;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
height: 23px;
width: 150px;
padding: 6px;
}
/* 4th Menu */
ul#navmenu li:hover li:hover li:hover li a,
ul#navmenu li.iehover li.iehover li.iehover li a {
background: #7A80A2;
color: #ffffff;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
height: 23px;
width: 150px;
padding: 6px;
}
/* 4th Menu Hover */
ul#navmenu li:hover li:hover li:hover li a:hover,
ul#navmenu li.iehover li.iehover li.iehover li a:hover {
background: #7A80A2;
color: #ffffff;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
height: 23px;
width: 150px;
padding: 6px;
}
ul#navmenu ul ul,
ul#navmenu ul ul ul {
display: none;
position: absolute;
top: 0;
left: 150px;
}
/* Do Not Move - Must Come Before display:block for Gecko */
ul#navmenu li:hover ul ul,
ul#navmenu li:hover ul ul ul,
ul#navmenu li.iehover ul ul,
ul#navmenu li.iehover ul ul ul {
display: none;
}
ul#navmenu li:hover ul,
ul#navmenu ul li:hover ul,
ul#navmenu ul ul li:hover ul,
ul#navmenu li.iehover ul,
ul#navmenu ul li.iehover ul,
ul#navmenu ul ul li.iehover ul {
display: block;
}
</style>
<script>
function loadXMLDoc(fname)
{
var xmlDoc;
// code for IE
if (window.ActiveXObject)
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation
&& document.implementation.createDocument)
{
xmlDoc=document.implementation.createDocument("","",null);
}
else
{
alert('Your browser cannot handle this script');
}
xmlDoc.async=false;
xmlDoc.load(fname);
return(xmlDoc);
}
function displayResult()
{
xml=loadXMLDoc("menu.xml");
xsl=loadXMLDoc("menu.xsl");
// code for IE
if (window.ActiveXObject)
{
ex=xml.transformNode(xsl);
document.getElementById("nav").innerHTML=ex;
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation
&& document.implementation.createDocument)
{
xsltProcessor=new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml,document);
document.getElementById("nav").appendChild(resultDocument);
}
}
</script>
</head>
<body bgcolor="#FFFFFF" onLoad="displayResult();">
<div id="shell">
<div id="nav" >
</div>
</div>
</body>
</html>
If you can use the server, then I'd recommend either JSON, or transform directly into XHTML there, and eschew JS completely (use a CSS-based foldout).
By the way, welcome to WebmasterWorld!
I tried doing this kind of thing once. only once - and along the way I became so annoyed by browser inconsistencies that I gave up and used a different method; something would work in IE but not in FF, then it would work in FF but not IE6... I ended up writing the thing again as a server-side web service.
I'm not saying it's impossible, and if there is a good cross-browser-compatible method, I'd like to know it... but sorry I don't have a solution for this one handy.
I'd suggest the answer - if one exists - is probably hiding somewhere in the Mozilla or MSDN documentation.
I'm not kidding. I avoid browser-side XSLT like the plague.
That way, it can be even simpler than XML.
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
can become:
<div class="catalog">
<div class="cd">
<div class="title">Empire Burlesque</div>
<div class="artist">Bob Dylan</div>
<div class="country">USA</div>
<div class="company">Columbia</div>
<div class="price">10.90</div>
<div class="year">1985</div>
</div>
<div class="cd">
<div class="title">Hide your heart</div>
<div class="artist">Bonnie Tyler</div>
<div class="country">UK</div>
<div class="company">CBS Records</div>
<div class="price">9.90</div>
<div class="year">1988</div>
</div>
</div>
Another thing: Hand-written XML isn't a good idea, even if engineers are doing it. It's a good idea to use an XML generator. You could write one pretty simply.
</babble>