四、 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;