敬业的IT人 >> 网站建设 >> Web编程 >> XML/Soap >> 用XSLT生成网页菜单(2)

用XSLT生成网页菜单(2)

敬业的IT人 互联网 佚名 2008-1-11 9:25:19
    四、 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="http://www.cncms.com.cn/xml/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风格的导航条制作教程》一文当中就是基于微软网站的导航条而写的,感兴趣的朋友可以参考一下。
粤ICP备06119539号
Copyright CiscoSky.Org,Some Rights Reserved.
Email:me1228#tom.com