Welcome to WebmasterWorld Guest from 18.208.159.25

Forum Moderators: open

Message Too Old, No Replies

building a multi level css menu with xml datasource

     
1:17 pm on May 15, 2008 (gmt 0)

New User

10+ Year Member

joined:Dec 2, 2005
posts: 8
votes: 0


Hi

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>

1:34 pm on May 15, 2008 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0


Why not use JSON [json.org] instead?

That's exactly what it's for.

2:15 pm on May 15, 2008 (gmt 0)

New User

10+ Year Member

joined:Dec 2, 2005
posts: 8
votes: 0


I don't get to choose the datasource file. It is an external xml file.
2:31 pm on May 15, 2008 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0


Are you trying to transform it in the browser, or can you read the file on the server, and apply the XSLT there?

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!

2:53 pm on May 15, 2008 (gmt 0)

New User

10+ Year Member

joined:Dec 2, 2005
posts: 8
votes: 0


thanks for the welcome, been a lurker for years.

Have to do it client side unfortunately, thus the problem. Normally I'd do it server side.

3:04 pm on May 15, 2008 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0


Eesh...I hate client-side XSLT, which is why I don't have experience in it. I'm not sure how much help I can be.
8:51 am on May 16, 2008 (gmt 0)

New User

10+ Year Member

joined:Dec 2, 2005
posts: 8
votes: 0


Anybody else have any ideas, I'm at a real loss here.
12:27 pm on May 16, 2008 (gmt 0)

Senior Member from CA 

WebmasterWorld Senior Member httpwebwitch is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Aug 29, 2003
posts:4061
votes: 0


XML load and XSLT transform, all in the browser, in memory (ie not a full-document transformation)... you'd think it's possible, wouldn't you. It just feels like there should be an easy way to do it, because the ingredients are so basic.

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.

12:39 pm on May 16, 2008 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0


I'd use AJAX to run the data through the server. Just have the sever include the file in a file_get_contents(), and have your way with it. Send JSON or XHTML back to the browser. This has the advantage of being incredibly flexible and browser-neutral.

I'm not kidding. I avoid browser-side XSLT like the plague.

12:56 pm on May 16, 2008 (gmt 0)

New User

10+ Year Member

joined:Dec 2, 2005
posts: 8
votes: 0


I wish their was a server but this is an offline app using a static html page to show info. The xml file is to centrally hold the menu items for easy updates.
1:07 pm on May 16, 2008 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0


Ohhh... Is there any way you can have the XML saved in an XHTML-compatible form?
1:15 pm on May 16, 2008 (gmt 0)

New User

10+ Year Member

joined:Dec 2, 2005
posts: 8
votes: 0


I don't know the expertise of the people who will be editing the xml file so I'd rather have it as simple as possible.
1:32 pm on May 16, 2008 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0


In that case, have them use <div> elements only, and assign a class/id to each <div>. You can use CSS to do all the rest.

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.

2:41 pm on May 16, 2008 (gmt 0)

Senior Member from CA 

WebmasterWorld Senior Member httpwebwitch is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Aug 29, 2003
posts:4061
votes: 0


yeah no kidding. Friday afternoon Mr Sales Dude forgets to close a <br/> tag or inserts a &copy; and the whole thing implodes. Even talented XML experts mess up well-formedness sometimes - I once found an entity encoding error in one of Yahoo's APIs, and they're irrefutable experts at producing valid XML. If they mess up (and I do, and you do, we all do), then you can be sure someone producing your XML is going to send you some badly-formed XML some day. Will your system validate, handle the problem, or fail gracefully? Is the integrity of your system critical?

</babble>

2:08 am on May 18, 2008 (gmt 0)

Senior Member from CA 

WebmasterWorld Senior Member httpwebwitch is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Aug 29, 2003
posts:4061
votes: 0


hey trancehead,
have you tried the JQuery XSLT plugin [jongma.org]?
11:55 am on May 19, 2008 (gmt 0)

New User

10+ Year Member

joined:Dec 2, 2005
posts: 8
votes: 0


Thanks for your help. Luckily the comapny that needs this has somebody that has the skills to do this. Don't ask me why the didn't use him earlier, that's a topic for another thread.