-
您的位置:首页 → 精文荟萃 → 破解文章 → 用C#与XML创建动态分层菜单
用C#与XML创建动态分层菜单
时间:2004/10/15 1:02:00来源:本站整理作者:蓝点我要评论(0)
-
从在复杂的B2B交易中的交换数据到为应用程序提供配置文件结构,XML在许多方面大显身手!由于XML不断地获得软件的支持,我们完全能够预见:XML的应用将不断增加。本文就介绍这样一种应用程序,它使用XML创建类似于Windows开始菜单的分层菜单系统,从而向终端用户提供更满意的Web体验。
这个应用程序将使用 C#、XML和服务器端Microsoft .Net框架,创建一个 DHTML 结构,IE4 或更高版本的浏览器可以操作它并在客户端动态显示。由于我们可以快速地访问服务器上的XML,并且XML能够描述层次之间的关系,因此它成为标记“父/子菜单”数据的一个最佳选择。
除了学习如何使用XML创建一个菜单应用程序外,我们还要介绍 .Net框架的主要 XML 类,它们位于 System.Xml 集合中。
什么是.Net集合(Assembly)
要在 C# 文件中使用XML,就必须引用一个特定的名称空间。 .Net平台中的一个名称空间是作为一个程序组件的组织系统使用的,它对于解决命名冲突很重要,这一点很象 XML中的 名称空间。这个基于 XML的菜单系统是用位于System.Xml集合中的System.Xml名称空间创建的。.Net SDK 是这样定义集合的:一个集合就是一个类型和资源的汇集信息,这些类和资源一起使用,形成一个功能的逻辑单元,即一个“逻辑”dll。
一个集合需要许多物理文件,如界面、类、资源文件等等,并且创建了关于文件如何一起工作的元数据。集合中还可能包含版本及安全信息。集合有许多好处,其中之一就是可以在ASP.NET应用程序中使用,而无须用regsvr32.exe向注册文件中增加一个类识别号(CLSID)。这样以来,集合的升级操作与将适当的集合复制到一个ASP.NET 应用程序的bin 目录中一样简单。现在我们就来仔细看一看那些建立在System.Xml名称空间和集合中的类。
如果你以前使用过Microsoft的 MSXML3分解器,就会发现使用System.Xml 集合中的类相当简单。这里的菜单应用程序只使用了这些主要集合类中的一部分:XmlNode、 XmlDocument、 XmlNodeList、 XmlNamedNodeMap、 DocumentNavigator、 XmlTextReader和 XmlTextWriter。
XmlDocument、 XmlNodeList和XmlNode类用来创建传递给客户端浏览器的菜单应用程序的结构。用XmlDocument类以一种安全线程(thread-safe)的方式从服务器上装载和分解本地或远程XML 文档。建立在一个字符串中的 XML标记也可以被装载或分解,从而在一个文档中创建、移动节点或取消节点的移动。XmlNodeList 类可以使我们列举一个节点的集合来访问一个特定属性,如名称、值或名称空间。最后,XmlNode类可以用来在XML文档中向一个用于检验的XmlNode 对象分配一个特定节点。
XmlNamedNodeMap类用来列举建立在一个元素类型选择中的属性集合。 DocumentNavigator、 XmlTextReader和XmlTextWriter类提供与XML一起使用所需要的额外功能。要特别说明的是,DocumentNavigator可以用来执行XPath查询,它被包含在XSLT转换中。XmlTextReader类提供对XML节点的只向前(forward-only)、无缓存的访问,从而使XML节点对大型XML文档也同样生效。XmlTextWriter类提供一个快速、只向前的指针模型,实现将 XML 内容写到一个流或一个文件中的目的。
在菜单应用程序中使用的XML 文档相对来说是较小的,因此我们可以在服务器端使用文档对象模式(DOM)来存取XML文档中的不同节点。当分解大型 XML文档时,就需要使用XmlTextReader 类所含有的只向前模型。
XML 代码
菜单应用程序使用了3个 XML 文档:menuItems.xml、menuItems2.xml 和menuItems3.xml,它们用于标记单独的菜单项目。XML的处理和操作由一个叫做xmlMenus.dll的集合完成,这个集合被服务器端的一个ASP.NET 文件createMenus.aspx所使用。在客户端的动态HTML (DHTML)内容使用了一个层叠格式表文件和一个JavaScript文件,这些文件联合在一起生成了本文开始部分的图示结果。
我们在List 1的代码显示了用来标记单独菜单项目的XML文档的一部分。文档中的主元素命名为menuItem,它可以包含一个名字和超级链接元素以及额外的menuItem 子元素。这种关系可以用来创建包含子菜单的菜单系统,就象Windows的开始菜单一样。
由于 XML已经标出了分层关系,因此就可以利用循环在不同元素之间行走:当使用XmlDocument、XmlNode和XmlNodeList类创建子节点时,我们可以反复调用WalkTree() 函数以颠倒父/子关系。其它的类如 ArrayList和 StreamWriter用于将相关菜单归类到数组中,然后在适当时间将所生成的菜单结构写入一个文件中。
XmlMenus集合的代码开始时要声明一个XmlHierMenu 名称空间,接下来要引用 System、 System.Xml、 System.Collections和System.IO 名称空间:
using System;
using System.Xml;
using System.Collections;
using System.IO;
在这部分代码之后要创建3个构造器。一个构造器不接收变量,只对变量进行初始化。下一个构造器接收一个图象文件的定制路径。最后一个构造器在不经常对XML菜单进行刷新的情况下,允许将由集合生成的输出存储到一个文件中。最后一个构造器所生成的文件可以被静态地包含在一个 ASP.NET文件中,而不是在各个Web页面请求时随时地生成。
在构造器之后,开始定义 CreateMenu()方法,具体请看List 2中的代码。
这个方法负责进行XML文档的装载和解析,找到根节点,然后在根的子节点之间循环。如果发现一个子节点本身还有子节点,就调用WalkTree() 方法,并且把这些子节点都传递到其中。如果这些子节点还有子节点,就再次调用 WalkTree()。这个过程循环进行直到不再发现增加的子节点。Walktree()方法的代码可以参看List 3。
在调用 WalkTree()方法并且对不同的节点进行分析的同时,要解析 menuItem节点,将来自其超级链接和名字节点的数据放在数组列表中。对整个 XML文档都进行解析之后,数组列表的内容就被传递回调用的ASP.NET的页面,然后使用Response对象写出信息。从这时起,客户端的 JavaScript代码就开始控制DHTML 菜单了。
在服务器端,我们使用一个 ASP.NET页面来开始菜单的创建过程。这个页面输入了与集合相关联的名称空间XmlHierMenu:
<%@ page language="C#" %>
<%@ Import Namespace="XmlHierMenu" %>
然后,将样式表文件和 JavaScript文件包含在文件的 代码区中。最后,在 ASP.NET 页面底部的代码用来引用上面提到的CreateMenu() 方法与WalkTree()方法,请看List 4。
在ASP.NET 页面中所找到的C# 代码只是建立了到不同的XML文档的路径,并且对 XmlMenu 类进行了例示。一旦对这个类进行了例示,就对 CreateMenu()方法进行调用。这个方法接收菜单名以及到这个菜单的XML文档的文件路径。在本例中,要创建3个名为menu1、 menu2和 menu3 的菜单,然后在一个ASP.NET页面中使用。这个应用程序在一个给定页面中可以支持无穷多的菜单,但是我们建议菜单数目不要过多,因为每增加一个菜单,发送到客户端的文件规模都会增加。
编译 C# 文件
现在我们已经看到了菜单应用程序的结构,接下来讨论一下使用哪些开关可以将C# 文件编译到一个集合中。在 .Net SDK 文档中,我们可以查询到一个所有编译开关的完整列表。
要想正确地编译 C# 文件以使它能用于一个ASP.NET 页面中,编译器就必须要知道包含了System.Xml 集合。这可以通过使用 /r 开关并在后面加上到集合的完整路径来完成。由于将要创建的 dll是一个库,因此就必须指定 /t开关,这样编译器就不再寻找一个静态的 Main() 方法。最后一个需要的开关是 /out ,它将告诉编译器输出的文件名是什么,以及将其放在哪里。
所有对 C# 编译器的调用都以 csc (C# 编译器)开始,然后指定适当的开关。编译器语法的最后一部分包括到已创建的 .cs 文件的路径。请看下面的编译文件的完整语法格式:
C:\>csc /r:System.Xml.dll /
t:library /out:d:\inetpub\wwwroot\
xml\bin\xmlMenus.dll d:\inetpub\
wwwroot\xml\menus\xmlMenus.cs
这行命令告诉编译器包含 System.Xml 集合、将文件作为一个库进行编译、将文件输出到 bin目录中、输入文件命名为xmlMenus.cs,输出文件名叫xmlMenus.dll。当输入回车键后,.cs文件就进行编译,生成的 dll将被放置在适当的文件夹中。
结束语
本文通过讲解一个应用程序的思路及实现代码,使我们对于使用Microsoft .Net平台中的一些集合和类有了一个很好的了解。随着进一步的学习,我们将看到,还会有其它一些集合和类可以以多种方式与本地和远程XML文档一起工作。
附list1:
附list2:
public string CreateMenu(
string startMenu,string file) {
string strOutput = "";
int i = 0;
ArrayList startArray = new ArrayList();
string strVariable = "";
string strTemp = "";
XmlDocument XMLDoc = new XmlDocument();
try {
XMLDoc.Load(file);
}
catch (Exception e) {
strOutput = e.GetBaseException().ToString();
return strOutput;
}
XmlNodeList nodeList =
XMLDoc.DocumentElement.ChildNodes;
foreach (XmlNode node in nodeList) {
XmlNode currentNode = node;
if (currentNode.HasChildNodes ==
true && currentNode.ChildNodes.Count>1) {
_strCurrentMenu = startMenu + "_" + (i+1);
string thisMenu = startMenu;
if (currentNode.ChildNodes.Count>2) {
strVariable = " thisMenu + "_span" + (i+1) + "\"
class='cellOff' onMouseOver=\"stateChange(
'" + _strCurrentMenu + "',this," +
_intLevel + ")\" onMouseOut=\"stateChange(
'',this,'')\">" + _strImage +
currentNode.ChildNodes[1].InnerText +
"
\n";
startArray.Add(strVariable);
WalkTree(currentNode);
} else {
strVariable = " "_span" + (i+1) + "\" class='cellOff'
onMouseOver=\"stateChange(
'',this,'');hideDiv(" + _intLevel + ")\"
onMouseOut=\"stateChange('',this,'')\"
onClick=\"location.href='" +
currentNode.ChildNodes[0].InnerText +
"'\">" + currentNode.ChildNodes[1].
InnerText + "
\n";
startArray.Add(strVariable);
}
}
i++;
}
startArray.TrimToSize();
_arrayNamesArray.Add(startMenu);
for (i=0;i strTemp += startArray[i];
}
_arrayHolderArray.Add(strTemp);
//Reverse Array order so we don't have to
//worry about the ZIndex of each div layer
_arrayHolderArray.Reverse();
_arrayNamesArray.Reverse();
//Loop through arrays and write out divs and
//their individual span content items
for (i=0;i<_arrayNamesArray.Count;i++) {
strOutput += "
class='clsMenu'>";
strOutput += _arrayHolderArray[i].ToString();
strOutput += "
\n";
}
_arrayHolderArray.Clear();
_arrayNamesArray.Clear();
if (_blnStaticMenus) {
StreamWriter writer =
new StreamWriter(File.Open(_strSaveToFile,
FileMode.OpenOrCreate, FileAccess.Write));
writer.Write(strOutput);
writer.Flush();
if (writer !=null) writer.Close();
}
return strOutput;
} //CreateMenus
附list3:
private void WalkTree(XmlNode node) {
_intLevel += 1;
string strVariable = "";
string strTemp = "";
ArrayList tempArray = new ArrayList();
for (int j=2;j XmlNode newNode = node.ChildNodes[j];
if (newNode.HasChildNodes == true &&
newNode.ChildNodes.Count>2) {
// Each node should have a 0=hyperlink and 1=text node so
// don't call the function again if there are just these
// children
_strCurrentMenu += "_" + (j-1);
string thisMenu = _strCurrentMenu.Substring(
0,_strCurrentMenu.Length-2);
strVariable = " "_span" + (j-1) + "\" class='cellOff'
onMouseOver=\"stateChange('" +
_strCurrentMenu + "',this," +
_intLevel + ")\" onMouseOut=\"stateChange(
'',this,'')\">" + _strImage +
newNode.ChildNodes[1].InnerText +
"
\n";
tempArray.Add(strVariable);
WalkTree(newNode);
} else {
strVariable = " strCurrentMenu + "_span" + (j-1) +
"\" class='cellOff' onMouseOver=
\"stateChange('',this,'');hideDiv(" +
_intLevel + ")\" onMouseOut=\"stateChange(
'',this,'')\" onClick=\"location.href='" +
newNode.ChildNodes[0].InnerText + "'\">" +
newNode.ChildNodes[1].InnerText +
"
\n";
tempArray.Add(strVariable);
}
}
tempArray.TrimToSize();
_arrayNamesArray.Add(_strCurrentMenu);
for (int i=0;i strTemp += tempArray[i];
}
_arrayHolderArray.Add(strTemp);
_strCurrentMenu = _strCurrentMenu.Substring(
0,_strCurrentMenu.Length-2);
//Exiting function so go back to
//previous menu version
_intLevel -= 1;
tempArray.Clear();
} // WalkTree
附list4:
// Create paths to xml files
string filepath = Server.MapPath("menuItems.xml");
string filepath2 = Server.MapPath("menuItems2.xml");
string filepath3 = Server.MapPath("menuItems3.xml");
// Following is constructor used to create a static menu
// file in cases where the menu does not change often.
// string saveToFile = Server.MapPath("test.aspx");
// XmlMenu menuSave = new XmlMenu(true,saveToFile);
// menuSave.CreateMenu("menu1",filepath);
// Instantiate XmlMenu object and call CreateMenu method
XmlMenu menu = new XmlMenu();
Response.Write(menu.CreateMenu("menu1",filepath));
Response.Write(menu.CreateMenu("menu2",filepath2));
Response.Write(menu.CreateMenu("menu3",filepath3));
|
相关阅读
Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么
-
热门文章
去除winrar注册框方法
最新文章
比特币病毒怎么破解 比去除winrar注册框方法
华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)通过Access破解MSSQL获得数据
人气排行
华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)qq相册密码破解方法去除winrar注册框方法(适应任何版本)怎么用手机破解收费游戏华为无线猫HG522破解如何给软件脱壳基础教程
查看所有0条评论>>