用XML实现弹出式菜单

xml|菜单

 

XML已经成为了新一代网络计算的世界语,这一点已经在各大软件公司的产品中逐步体现出来。XML本身并不是一种计算语言,而更多表现为一种数据描述的格式。相对于HTML,它更多具有数据定义的特性,而相对于数据库,它又更加灵活和适于在网络上传输。围绕XML的相关技术也层出不穷,如XSL, XSLT等,它们的配合让我们能够真正在XML上开始完成一些有趣的任务。 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

本文就是以一个XML初学者的角度在网页上实现一个动态弹出式菜单。对于同样希望了解XML与表现无关的特性的读者应当有所帮助。

>应用情景

我们经常在一些网站看到形形色色的菜单形式,大部分的菜单都借用了DHTML的一些特性实现,但是想好好地利用这些已有的菜单实现一些自己的菜单并不容易。首先是必须从它们的整个页面中把一些代码“分析”,其次要分析其中的显示方式与显示内容的关系,如果自己的菜单结构和显示方式不同于其它网站的设计,就得花更多的功夫去研究新的显示方法。

而我们希望实现一个可以动态调整的菜单结构,这种菜单应当可以适用于我们所要完成的整个一个网站。一旦我们的网页页面设计发生了变化,我们可以灵活地把菜单显示方式改变,适应新的网页整体风格。

我们所希望实现的菜单首先可以表现为以下样子:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
图1:我们想实现的弹出式菜单的一种外观

实现方法

在大量接触HTML后,今天的网页程序设计中我们更多地愿意直接把一个页面的样子用所见即所得的编辑工具(如Frontpage, Dreamweaver等)“画”出来,而不再习惯于利用数据结构的方式设计能够通用的模块。为了能够达到我们的目的,我们又一次地开始重新考虑如何定义一个通用的菜单数据结构来描述一个菜单的信息,然后再使用一个显示模块表现这些数据信息,如果改变显示模块的一些参数,就可以实现相同菜单内容的不同外观和行为。

在了解了XML的基本定义方法之后,我们定义了如下的示范数据:

列表1: 一个示范性菜单数据结构XML

 
<?xml version="1.0" encoding="gb2312" ?>
<?xml:stylesheet type="text/xsl" href="menus.xsl"?>

<TOPICLIST TYPE="动态菜单">

<TOPICS TYPE="网络好去处">
<TOPIC>
<TITLE>中国XML联盟</TITLE>
<URL>http://www.xml.org.cn</URL>
</TOPIC>
<TOPIC>
<TITLE>易方软件公司</TITLE>
<URL>http://www.tangram.com.cn</URL>
</TOPIC>
<TOPIC>
<TITLE>微软MSDN</TITLE>
<URL>http://msdn.microsoft.com</URL>
</TOPIC>
</TOPICS>

<TOPICS TYPE="XML的应用实例">
<TOPIC>
<TITLE>biztalk</TITLE>
<URL>http://www.biztalk.org</URL>
</TOPIC>
</TOPICS>

<TOPICS TYPE="XML特性">
<TOPIC>
<TITLE>精简</TITLE>
<URL>express.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>自解释</TITLE>
<URL>description.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>可交换</TITLE>
<URL>exchange.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>与显示无关</TITLE>
<URL>nopresentation.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>精简</TITLE>
<URL>express.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>自解释</TITLE>
<URL>description.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>可交换</TITLE>
<URL>exchange.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>与显示无关</TITLE>
<URL>nopresentation.htm</URL>
</TOPIC>
</TOPICS>

<TOPICS TYPE="联系作者">
<TOPIC>
<TITLE>Isaac M.</TITLE>
<URL>mailto: isaac@tangram.com.cn</URL>
</TOPIC>
</TOPICS>
<TOPICS TYPE="小试牛刀">
<TOPIC>
<TITLE>红色牛刀</TITLE>
<URL>red.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>白色牛刀</TITLE>
<URL>white.htm</URL>
</TOPIC>
<TOPIC>
<TITLE>褐色牛刀</TITLE>
<URL>brown.htm</URL>
</TOPIC>
</TOPICS>
</TOPICLIST>

 

在这段数据中,菜单的主要项目和子项分别使用<TOPICS>和<TOPIC>元素表示,一目了然。同时你也可以看到,我们已经为这段数据指定了一段外部的转化为DHTML的XSL代码:

  <?xml:stylesheet type="text/xsl" href="menus.xsl"?>

这行信息能够让IE自动把菜单的数据结构与一个特定的XSL结合在一起并转化为DHTML进行解释。另外,为了在IE中正确解释中文内容,在这段数据结构的第一个部分加入了encoding="gb2312" 的描述。

学习定义XSL是一个稍微麻烦的事情,因为XSL既像一段DHTML的描述,由好像有可执行程序的功能。假如你比较熟悉DHTML,应当很容易掌握XSL的要领,但是自己定义的过程,应当配合XML一起,一边测试一边定义是一个不错的方法。我们在自己的菜单中,采用了<DIV>把菜单的项目逐个解析成为DHTML的元素。

 

列表2:能够表现我们所定义的菜单数据的一种XSL (Menus.xsl)

 <?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

<!-- MENUS.XSL -->

<xsl:template match="/">
<HTML>
<HEAD>
<TITLE><xsl:value-of select="TOPICLIST/@TYPE" /></TITLE>
<LINK REL="stylesheet" TYPE="text/css" HREF="menus.css" />
<SCRIPT LANGUAGE="JScript" SRC="menus.js"></SCRIPT>
</HEAD>
<BODY>
<H1><xsl:value-of select="TOPICLIST/@TYPE" /></H1>

<!-- BUILD MENUBAR -->

<DIV ID="divMenuBar">
<TABLE ID="tblMenuBar" BORDER="0">
<TR>
<xsl:for-each select="//TOPICS[TOPIC]">
<TD CLASS="clsMenuBarItem">
<xsl:attribute name="ID">tdMenuBarItem<xsl:value-of select="@TYPE" /></xsl:attribute>
<xsl:value-of select="@TYPE" />
</TD>
<xsl:if test="context()[not(end())]">
<TD>|</TD>
</xsl:if>
</xsl:for-each>
</TR>
</TABLE>
</DIV>

<!-- BUILD INDIVIDUAL MENUS -->

<xsl:for-each select="//TOPICS[TOPIC]">
<DIV CLASS="clsMenu">
<xsl:attribute name="ID">divMenu<xsl:value-of select="@TYPE" /></xsl:attribute>
<DIV CLASS="clsMenuSpacer"></DIV>
<xsl:for-each select="TOPIC">
<DIV>
<A TARGET="main">
<xsl:attribute name="HREF"><xsl:value-of select="URL" /></xsl:attribute>
<xsl:value-of select="TITLE" />
</A>
</DIV>
</xsl:for-each>
</DIV>
</xsl:for-each>

</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
 

在最早的Menu.xsl定义中,我们把菜单的交互方式(即如何响应鼠标的动作),以及颜色和字体等风格元素都与XSL结合在一起。但是我们发现还可以分离,一边保留更大的灵活性。所以我们又定义了Menus.css和Menus.js文件,单独定义了菜单主项和子项的外观等特性,以及如何响应用户的动作,这样我们又获得了进一步的灵活性。

列表3:在XSL中可以调整的格式表StyleSheet (Menus.css)

  /* MENUS.CSS */

BODY { font-family:verdana; font-size:60%; background-color:ffffff; }
H1 { font-size:120%; font-style:italic; }

DIV#divMenuBar { background-color:#6699cc; }
TABLE#tblMenuBar TD { font-size:60%; color:white; padding:0px 5px 0px 5px; cursor:default; }
TABLE#tblMenuBar TD.clsMenuBarItem { font-weight:bold; cursor:hand; }

DIV.clsMenu {
font-size:100%; background-color:#000000;
position:absolute; visibility:hidden; width:130px;
padding:5px 5px 5px 8px; border-top:1 white solid;
}
DIV.clsMenu A { text-decoration:none; color:white; font-weight:bold; }
DIV.clsMenu A:hover { color:blue; }

菜单的解析代码Menus.xsl中还包含了一个外部的Javascript代码文件,这样我们的动态菜单的各个模块就可以协同工作了。

列表4:实现Menu的交互方式的代码 (Menus.js)

  /* MENUS.JS */

var eOpenMenu = null;

function OpenMenu(eSrc,eMenu)
{
eMenu.style.left = eSrc.offsetLeft + divMenuBar.offsetLeft;
eMenu.style.top = divMenuBar.offsetHeight + divMenuBar.offsetTop;
eMenu.style.visibility = "visible";
eOpenMenu = eMenu;
}

function CloseMenu(eMenu)
{
eMenu.style.visibility = "hidden";
eOpenMenu = null;
}

function document.onmouseover()
{
var eSrc = window.event.srcElement;
if ("clsMenuBarItem" == eSrc.className)
{
eSrc.style.color = "moccasin";
var eMenu = document.all[eSrc.id.replace("tdMenuBarItem","divMenu")];
if (eOpenMenu && eOpenMenu != eMenu)
{
CloseMenu(eOpenMenu);
}
if (eMenu)
{
OpenMenu(eSrc,eMenu);
}
}
else if (eOpenMenu && !eOpenMenu.contains(eSrc) && !divMenuBar.contains(eSrc))
{
CloseMenu(eOpenMenu);
}
}

function document.onmouseout()
{
var eSrc = window.event.srcElement;
if ("clsMenuBarItem" == eSrc.className)
{
eSrc.style.color = "";
}
}

下面我们只要对以上与数据、交互方式和风格相关的各种文件进行一些参数修改就能够改变这个菜单模块的行为和表现了。修改Menu.xml能够动态增加菜单的内容信息,修改menu.xsl能够改变菜单的格局,修改menus.js能够改变菜单的交互方式,修改menus.css能够改变菜单的颜色、字体等外观。

例如,只是在Menu.xsl和menu.js修改很少代码,就能够让以上的菜单信息表现出完全不同的一种交互风格,成为垂直型的弹出菜单。如果你有兴趣,就在示例的代码中自己修改一下,变成自己的菜单代码吧(在我们提供的下载代码中,menus2.xsl和menus2.js等都是修改后的实例)。

图2:改变XSL文件参数后弹出式菜单的另一种外观

总结

通过这样一个简单却很有趣的编程经历,我们发现XML确实是一种非常灵活的网络信息表现语言,它的与显示无关的特性能够让我们在这个初步探索的基础上为它增加更多的特性。例如,我们的下一步目标就是把menus.xml用一段ASP程序所替代,在我们的网站数据库中动态提取当前页面所需要的菜单内容,然后再结合增强的XSL和Javascript编写更加复杂的菜单模块。

 

时间: 2024-12-02 04:42:55

用XML实现弹出式菜单的相关文章

XML 论坛

您知道 Microsoft Internet Explorer 5.5 具有编辑 HTML 的内置支持吗?我一直想有一个基于 XML 的好工具来做联机讨论,和新闻组差不多,但是结构性更强,好让我能轻松地添加新的功能.我一直希望这类工具中能有这些功能:轻松维护 - 能删掉我自己张贴的内容,或者指定一些管理员,让他们可以轻松删掉贴子.完整地复制这些论坛的部署和管理.用户分级 - 可以根据有用程度对最终用户的张贴内容进行分级.这样,其他用户就可以轻松地找到有价值的内容.速度 - 相对于 Intrane

PHP遍历XML文档所有节点的方法

 这篇文章主要介绍了PHP遍历XML文档所有节点的方法,实例分析了php操作XML文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了PHP遍历XML文档所有节点的方法.分享给大家供大家参考.具体实现方法如下: 1. contact.xml代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 <contact id="43956"> <personal> <name> <first>J</fir

PHP往XML中添加节点的方法

 这篇文章主要介绍了PHP往XML中添加节点的方法,涉及php操作XML文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了PHP往XML中添加节点的方法.分享给大家供大家参考.具体方法如下: 1. contacts.xml代码 代码如下: <contact id="43956"> <personal> <name> <first>J</first> <middle>J</middl

vs2010新建项目是表如下图的错误怎么解决?按图中的路径寻找不到activitylog.xml

问题描述 vs2010新建项目是表如下图的错误怎么解决?按图中的路径寻找不到activitylog.xml

用asp.net和xml做的新闻更新系统(3)

asp.net|xml 最后,大家来看一下最负责的一个页面,这个页面的作用就是用来建立新的xml数据. manage.aspx </P><P><%@ Import Namespace="System.Xml.Xsl" %> <%@ Import Namespace="System.Xml" %> <%@ Assembly Name="System.Xml" %> <%@ Impor

logback.xml

<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender&quo

使用 Oracle XQuery 查询、构建和转换 XML

oracle|xml|转换 在 Oracle 数据库 10g 第 2 版中,Oracle 引入了一个与该数据库集成的全功能自带 XQuery 引擎,该引擎可用于完成与开发支持 XML 的应用程序相关的各种任务.XQuery 是一种用于处理 XML 数据模型的查询语言,它实际上可操作任何类型的可用 XML 表达的数据.尽管 Oracle XQuery 实施使您可以使用数据库数据和外部数据源,但在处理数据库中存储的结构化数据方面,Oracle XML DB 通常可以显著提高性能. 本文提供的示例不仅

js与xml交互理论和示例

---------------------------------------------------js+xml--------------------------------------------------------------------------- DOM2级在 document.implementation 中引入了 createDocument() 方法. IE9+. Firefox. Opera. Chrome 和 Safari 都支持这个方法. 想一想, 或许你还记得可以

JSP与XML的结合

js|xml 综述:可扩展标注语言(eXtensible Markup Language,XML)正被迅速的运用于业界,它已作为与平台.语言和协议无关的格式描述和交换数据的广泛应用标准.XML和它的辅助规范可用于描述数据的文档表现,描述XML文档类型的限制,描述XML文档和资源之间的链接,描述XML文档的自动转换和格式化. 如何开发自定义标签库? 我使用JSP和ASP编程已经有一段颇长的时间了,在两种服务器端的编程方式中,我越来越觉得JSP的功能要强大得多.不提别的,其中JSP的标签库就是我选择