用XSLT生成网页菜单

菜单|网页

  【声明】本文已在《程序员》杂志发表。本站转载纯属个人学习和珍藏之举,绝无侵犯版权之嫌。如作者或相关出版商认为转载有何不妥,请来信告知,必立即删除!另,在此对原文的排版格式作了一些修改,但原文未改动一字。
  【演示】观看本文最终结果演示页面请 单击这里
  【正文】
  一、 概述
一个好的导航 (navigation) 系统能增加网页的可读性和美观性,尤其是当网站内容比较丰富时,其逻辑结构更加需要用好导航系统来组织,使得网页读者知道其所在的位置以及还有那些内容可以浏览。导航系统中很重要的一个组成部分就是网页菜单。
普通 Windows 应用程序一般都有一个菜单系统,但是在网页中实现菜单要复杂一些。因为 Windows 操作系统中菜单是标准的用户界面接口,编制Windows 应用程序时,只需要描述菜单,菜单的显示和调用则由 Windows负责。在网页中则情况不同,HTML 没有菜单规范,网页开发者必须自己利用 DHTML 和 JavaScript 来实现菜单的显示和调用等功能。编制这样的程序还是比较复杂的。加上各种浏览器实现的DHTML 和 JavaScript 有差异,又使得原本已经复杂的网页菜单程序更加复杂。
本文将介绍用 XML 和 XSLT 来生成网页菜单的方法,它将使得网页开发者只需要描述菜单,而不用担心那些复杂的JavaScript程序,使得制作网页菜单比做 Windows 程序的菜单还要简单。

  二、 菜单的定义
先从菜单的逻辑概念讲起。所谓菜单,包含了一组菜单项,每个菜单项,具有属性标题和连接,菜单项又可以包含一组子菜单项,从而形成一个嵌套的树状结构
树状结构的菜单
  如图所示的结构很容易用 XML 来描述 (menu.xml)。

XML (eXtensible Markup Language,扩展标记语言) 是一种数据格式[1],它的特点是人们能非常容易读懂其中的含义,例如上面所示的菜单结构就一目了然。不仅仅是人能容易看懂 XML,计算机也能非常容易读懂其中的含义,这句话的含义是处理XML的程序已经非常普及,Windows下有MSXML[5],Java下有JAXP,即几乎所有平台上都有了XML处理程序[7][8]。并且处理XML有标准的办法,比如本文将用到的 XSLT (eXtensible Stylesheet Language Transformation, 扩展样式语言转换)就是将XML格式的数据转化到另外一种格式的标准方法[2][3][4]。
如果我们能用 XSLT 转化上述菜单的XML到网页上的菜单,那么制作网页菜单就比较简单了。因为编辑菜单的XML非常容易,普通的文本编辑器就可以了。
实现网页菜单的DHTML和JavaScript程序常常被制作成程序库的形式,称为网页菜单引擎。这些引擎都提供调用的接口,使得我们能够定制(customize)我们自己的菜单,但问题是定制菜单需要修改这些程序,比较麻烦也容易出错。
我们要解决的就是用XSLT根据菜单的XML,自动生成调用接口。
先让我们看看有哪些现成可用的网页菜单引擎。

  三、 网页菜单引擎
  因特网上有很多JavaScript资源网站,dynamicdrive.com 就是其中很优秀的一个。那里有许多很好的JavaScript程序可供下载使用,尤其是它的"Menus and Navigation Systems"分类中收集了不少网页菜单引擎。经过比较,我们选择使用"HV menu" (http://www.dynamicdrive.com/dynamicindex1/hvmenu/index.htm)。 HV menu 的优点是既可以做水平排列的菜单,又可以做垂直排列的菜单;可以包含多层子菜单结构;可以自定义菜单的字体、颜色、对齐方式;以及支持IE4+, NS4, NS6+等多种浏览器。
"HV menu"的程序库为 menu_com.js 文件。它的接口规范是:
MenuX=new Array(Text to show, Link, background image (optional), number of sub elements, height, width);
  因此在网页中使用这个菜单引擎的 JavaScript 函数调用为:
<script>
Menu1=new Array('论坛首页','http://www.delphibbs.com', '', 4, 20, 120);
Menu2=new Array('论坛分类','', '', 8, 20, 120);
Menu3=new Array('我的论坛','', '', 5, 20, 120);
Menu4=new Array('富翁用户','', '', 3, 20, 120);
Menu5=new Array('大富翁系列','', '', 3, 20, 120);
Menu6=new Array('帮助','', '', 4, 20, 120);
Menu6_1=new Array('使用说明','tutorial.htm', '', 0, 20, 120);
Menu6_2=new Array('常见问题','faq.htm', '', 0, 20, 120);
Menu6_3=new Array('关于我们','aboutus.htm', '', 0, 20, 120);
Menu6_4=new Array('联系我们','contactus.htm', '', 0, 20, 120);
</script>
  下面我们将用XSLT把菜单的XML转换为上述函数调用。

  四、 XSLT
  转换菜单的XML (menu.xsl) 的XSLT (menu.xsl) 为:
<?xml version="1.0" encoding="gb2312" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Menu Test</TITLE>
</HEAD>
<BODY leftmargin="0" topmargin="0">
<xsl:apply-templates select="menus"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="menus">
<script>
var NoOffFirstLineMenus=<xsl:value-of select="count(child::*)"/>;
var StartTop=<xsl:value-of select="@top"/>;
var StartLeft=<xsl:value-of select="@left"/>;
var FirstLineHorizontal=<xsl:value-of select="@style"/>;
<xsl:apply-templates select="menu">
<xsl:with-param name="pr" select="''"/>
</xsl:apply-templates>
</script>
<script type="text/javascript" src="menu_com.js"/>
</xsl:template>
<xsl:template match="menu">
<xsl:param name="pr"/>
Menu<xsl:value-of select=""/><xsl:value-of select="position()"/>=new Array('<xsl:value-of select="@caption"/>','<xsl:value-of select="@url"/>', '', <xsl:value-of select="count(child::*)"/>, 20, 120);
<xsl:if test="count(child::*) > 0">
<xsl:apply-templates select="menu">
<xsl:with-param name="pr" select="concat(,position(), '_')"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这里XSLT一共有三个模板。
第一个模板 <xsl:template match="/"> 它生成简单的HTML框架和一个空白的网页,除了调用第二个模板来插入菜单外,没有其他功能。实际应用中可以扩充这个模板加入网页的内容。
第二个模板 <xsl:template match="menus"> 读取存储为 menus 属性的top, left和style控制网页菜单的位置和类型(style=0为垂直菜单,style=1为水平菜单), 并且调用第三个模板绘制菜单项。
第三个模板 <xsl:template match="menu"> 生成了各个菜单项,它能递归处理嵌套子菜单项的情况。这里使用了三个 XSLT 函数[4]:position() 用于监测菜单的顺序号,count(child::*) 用于判别是否具有子菜单,concat(,position(), '_') 最终生成了HV menu所需要的菜单变量名。

  五、 实例
  我们用一段 Javascript (test _menu.htm) 实现XSLT转换,以及显示转换后的效果。
<script>
load_xml("menu.xml", "menu.xsl");
function load_xml(xmlf, xslf) {
try {
var myxml = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
myxml.async = false;
myxml.load(xmlf);
//alert(myxml.xml);
var myxsl = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
myxsl.async = false;
myxsl.load(xslf);
html = myxml.transformNode(myxsl);
document.write(html);
}
catch (exception) {
alert(exception.description);
}
}
</script>
这段程序在 IE 浏览器中创建MSXML[5]对象,然后输出结果 HTML。读者可以尝试下载本文的范例程序[8],实际体验网页菜单的效果。


 


鉴于Netscape浏览器不支持创建MSXML对象,我们可以在IIS服务器端转换后的返回 HTML[6]。本文介绍的网页菜单就能在Netscape浏览器中显示和运行。

  六、 结论
用XML来表达菜单结构非常方便并且易于理解,当通过本文介绍的XSLT把菜单XML转换为网页菜单引擎的调用接口后,为网页制作菜单就十分容易了,只需要用普通的文本编辑器编辑XML文件。本文使用了 HV Menu引擎,如果使用其他的引擎,还可以编制一个类似XSLT来配合调用引擎的接口。最后,XML和XSLT是平台无关的标准,我们还可以在apache服务器[7]中和JSP服务器[8]中使用本文的方法。
  【学习心得】
本文是学习XML及XSL技术的一个很好的实例。不过使用XML和XSL制作网页菜单仅仅是它们的一个很小的应用方面,XML和XSL的使用还有更多更加广泛的应用值得我们去学习和探讨。
本文中所制作的菜单效果虽然已经很出色,但是还是具有一定的缺点。例如菜单的位置控制、样式的扩充性,当子菜单过长时(超过浏览器纵向显示的长度)无法正确显示不可见的子菜单项等等。不过本文所使用的JS脚本给我们留出了很多扩展功能的接口函数。在长达25KB、600行的JS文件中,我们可以对菜单效果做进一步的改动。
另外,微软的网站以及MSDN的网站的导航条也运用了XML和XSL技术,我写的《仿XP风格的导航条制作教程》一文当中就是基于微软网站的导航条而写的,感兴趣的朋友可以参考一下。

时间: 2024-10-27 02:17:31

用XSLT生成网页菜单的相关文章

网页菜单详解

 首先看这下面的例子(鼠标移上去): Link 1 Link 2 Link 3 Link N 菜单实例 类似这样的仿Windows下拉菜单,在网上是比较常见的,最初出现在微软网站上,之后被大量效仿. 事实上制作这样一个模拟菜单也并不是一件很困难的事,比如上面的例子代码如下: ------------------------------------------- <!-- 样式部分 --> <style type=text/css> td,div { font: normal 12p

网页菜单工厂 精彩网页菜单轻松完成

菜单|网页 要是能够像那些专业站点一样制作出令人心动的网页菜单当然是再好不过的了,如果你并不会这些Javascript技术也没有关系,就由WebMenuShop在短短的几分钟之内让你的主页增色不少. WebMenuShop是一款用于快速建立网页菜单的软件,可以很轻松的制作形式多样的网页菜单,在制作过程中可以即时预览所得到的菜单内容,并且能够很方便地把菜单保存下来作为他用.而且值得一提的是,整个WebMenuShop的菜单制作流程只有四个步骤,因此很快就能够轻松搞定这一切. 第一步:选择菜单的风格

Flash8制作动态开门效果网页菜单

菜单|动态|网页 今天给大家讲解一个如何利用Flash制作动态网页菜单,如果好你就可以直接拿去用了!你也可以自己改进,改进好了别忘了去论坛告诉一声啊! 先看效果和源文件: 点击这里下载源文件 制作方法非常简单,在这里给大家简单的叙述一下!如果不明白就看源文件吧! 首先制作五个影片剪辑片段,说说方法,建立两个图层,下面这个图层绘制一个矩形,至于填充为什么颜色按你的喜好定就可以了!上面的图层输入要显示的文字.然后分别都在第15帧插入关键帧,下面的矩形稍微调整一下形状,上面的文字层稍微向上移动一点位置

使用Fireworks 8生成网页

案例说明 此案例为<<使用Fireworks 8位图工具制作网页效果图>>的姊妹篇.前面已经给大家介绍了网页效果图的制作,这里要介绍的内容是如何把效果图生成网页.这也是网站制作中最重要的一部分.主要介绍的Fireworks如何和Dreamweaver进行协同工作.本例主要分为4个部分,希望大家能够通过这个例子得到一些启发,由于笔者的水平有限,错误的地方还希望大家批评指正. 1.1 创建Web站点 首先来创建WEB站点,具体操作步骤如下: 1.启动Dreamweaver 8软件,选择

使用photoshop生成网页的方法

  使用photoshop生成网页的方法          方法: 1.在这里,我借用百度经验的主页来给大家演一下(嘻嘻).打开photoshop,打开设计好的图片. 2.一般来说,我们需要使用切片工具将它分为几个区域.一方面网页不至于过大而难以加载,另一方面也方便在dreamweaver中按区域来修改. 3.将图片.文字等按照自己的设计需求来分割.在这里我就粗略的切一下.切完后也可以及时修改区域的大小. 4.我们选择文件,存储为web格式. 5.这时会跳出来一个窗口,你可以在其中在此简单修改每

js随机生成网页背景颜色的方法

 这篇文章主要介绍了js随机生成网页背景颜色的方法,涉及javascript操作背景色的技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了js随机生成网页背景颜色的方法.分享给大家供大家参考.具体实现方法如下:   代码如下: <HTML> <HEAD> <TITLE>随机生成网页背景颜色的JS特效</TITLE> <STYLE> .30pt{font-size:30pt;color:#de3076} </STYLE&

asp.net TreeView递归循环子节点生成树形菜单实例_实用技巧

本文实例讲述了asp.net TreeView递归循环子节点生成树形菜单的方法.分享给大家供大家参考,具体如下: 这里主要用到递归循环获取子结点 /// <summary> /// 生成根节点 /// </summary> /// <param name="treeview"></param> protected void BindTreeView(long ID, TreeView treeview) { DataTable dt =

JavaScript实现自动生成网页元素功能(按钮、文本等)_javascript技巧

创建元素的方法: 1.利用createTextNode()创建一个文本对象 2.利用createElement()创建一个标签对象 3.直接利用容器标签中的一个属性:innerHTML-----本质上改该标签容器中的"html代码",不是我们认为的对象树的操作 详解代码: <body> <input type="button" value="创建并添加节点1" onclick="addNode1()"/>

jquery+CSS3实现淘宝移动网页菜单效果_jquery

本文实例讲述了jquery+CSS3实现淘宝移动网页菜单效果.分享给大家供大家参考.具体如下: 这是一款基于jquery+CSS3实现的淘宝移动网页菜单,其实这个菜单动画并不复杂,只有缩放和位移.难点是用了扇形结构,而且还要实现扇形的链接区域,这个就费脑筋了,最后采用了传统的图片map来做热区,效果还不错.相信肯定有更好的解决方法. 先来看看运行效果截图: 在线演示地址如下: http://demo.jb51.net/js/2015/jquery-css3-taobao-phone-menu-c