15.2 操作XML数据
XML数据格式是.Net平台下面通用的数据格式,也就是说,在.NET平台下,几乎所有的数据都是以XML数据进行传输的,从数据库操作到Web Service无一例外!而作为微软首推的.NET编程语言C#来说,它对XML数据的操作也是非常方便的。
15.2.1 DOM概述
XML语言仅仅是一种信息交换的载体,是一种信息交换的方法。而要使用XML文档则必须通过使用一种称为“接口”的技术。正如使用ODBC接口访问数据库一样,DOM接口应用程序使得对XML文档的访问变得简单。
DOM(Document Object Model)是一个程序接口,应用程序和脚本可以通过这个接口访问和修改XML文档数据。
DOM接口定义了一系列对象来实现对XML文档数据的访问和修改。DOM接口将XML文档转换为树型的文档结构,应用程序通过树型文档对XML文档进行层次化的访问,从而实现对XML文档的操作,比如访问树的节点、创建新节点等。
微软大力支持XML技术,在.NET框架中实现了对DOM规范的良好支持,并提供了一些扩展技术,使得程序员对XML文档的处理更加简便。而基于.NET框架的ASP.NET,可以充分使用.NET类库来实现对DOM的支持。
.NET类库中支持DOM的类主要存在于System.Xml和System.Xml.XmlDocument命名空间中。这些类分为两个层次:基础类和扩展类。基础类组包括了用来编写操作XML文档的应用程序所需要的类;扩展类被定义用来简化程序员的开发工作的类。
在基础类中包含了三个类:
● XmlNode类用来表示文档树中的单个节点,它描述了XML文档中各种具体节点类型的共性,它是一个抽象类,在扩展类层次中有它的具体实现。
● XmlNodeList类用来表示一个节点的有序集合,它提供了对迭代操作和索引器的支持。
● XmlNamedNodeMap类用来表示一个节点的集合,该集合中的元素可以使用节点名或索引来访问,支持了使用节点名称和迭代器来对属性集合的访问,并且包含了对命名空间的支持。
扩展类中主要包括了以下几个由XmlNode类派生出来的类,如表15-5所示。
表15-5 扩展类包含的类
15.2.2 创建XML文档
创建XML文档的方法有两种。
(1)创建不带参数的XmlDocument,代码如下。
以上代码,使用了不带参数的构造函数创建一个XmlDocument对象doc。
(2)创建一个XmlDocument并将XmlNameTable作为参数传递给它。
XmlNameTable类是原子化字符串对象的表。该表为XML分析器提供了一种高效的方法,即对XML文档中所有重复的元素和属性名使用相同的字符串对象。创建文档时,将自动创建XmlNameTable,并在加载此文档时用属性和元素名加载XmlNameTable。如果已经有一个包含名称表的文档,且这些名称在另一个文档中会很有用,则可使用将XmlNameTable作为参数的Load方法创建一个新文档。使用此方法创建文档后,该文档使用现有XmlNameTable,后者包含所有已从其他文档加载到此文档中的属性和元素。它可用于有效地比较元素和属性名。以下示例是创建带参数的XmlDocument的代码:
以上代码,使用带参数的构造函数创建一个XmlDocument对象doc,其中System.Xml是XmlDocument的命名空间。
15.2.3 保存XML文档
XML创建完毕必须使用Save方法保存XML文档。Save方法有4个重载方法。
● Save(string filename):将文档保存到文件filename的位置。
● Save(System.IO.Stream outStream):保存到流outStream中,流的概念存在于文件操作中。
● Save(System.IO.TextWriter writer):保存到TextWriter中,TextWriter也是文件操作中的一个类。
● Save(XmlWriter w):保存到XmlWriter中。
以下代码演示如向实现对Xml文档的保存:
在以上代码中,第1行创建一个XmlDocument对象doc。第2行调用doc对象的Save方法将文档数据到当前程序的XMLFile.xml文件中。
15.2.4 将XML读入文档
DOM可以将不同格式的XML读入内存,这些格式可以是字符串、流、URL、文本读取器或XmlReader的派生类。
读取的XML数据的方法有两种。
(1)Load方法,该方法加载指定的XML数据。总共包含4个重载函数。
● XmlDocument.Load(Stream):从指定的流加载XML文档。
● XmlDocument.Load(String):从指定的URL加载XML文档。
● XmlDocument.Load(TextReader):从指定的TextReader加载XML文档。
● XmlDocument.Load(XmlReader):从指定的XmlReader加载XML文档。
(2)LoadXML方法,该方法没有重载函数,仅仅是XmlDocument.LoadXML(String),从字符串中读取XML。
【实例15-3】读入XML文档
本实例使用XmlDocument对象加载XML字符串,然后将XML数据保存到一个XML的文件中,具体实现步骤如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例15-3”。
02 在该网站中创建一个名为XMLFile.xml的XML文件。
03 在网站根目录下创建一个名为Default.aspx的窗体文件,单击自动生成的Default.aspx.cs文件,在该文件中编写如下逻辑代码:
上面的代码中第1行定义处理页面Page加载事件Load的方法。第2行创建一个XmlDocument对象doc。第3行~第10行利用doc对象的LoadXml方法从字符串中把XML数据加载到doc中,分别添加了6个标签和标签的内容。第11行利用doc的Save方法把XML数据保存到XMLFile.xml文件中。
04 用右键单击XMLFile.xml文件,在弹出的菜单中选择“在浏览器中查看”命令。运行后的效果如图15-7所示。
图15-7 运行效果
15.2.5 选择节点
ASP.NET的DOM提供了基于XPath的导航方法,使用这些导航方法可以方便查询DOM中的信息。
DOM提供了两种XPath导航方法。
● SelectSingleNode方法:返回符合选择条件的第一个节点。
● SelectNodes方法:返回包含匹配节点的XmlNodeList。
【实例15-4】选择节点
本实例使用SelectNodes方法从XML文档中获取news节点,并把获得每个节点的数据输出到页面上,具体实现步骤如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例15-4”。
02 在该网站中创建一个XMLFile.xml文件,文件中的内容与本章“实例15-1”中XMLFile.xml文件相同。
03 在网站根目录下创建一个名为Default.aspx的窗体文件,双击自动生成的Default.aspx.cs文件,在该文件中编写如下逻辑代码:
上面的代码中第1行定义处理页面Page加载事件Load的方法。第2行创建DOM对象doc。第3行把XML文档通过Load方法装入doc。第4行定义节点列表XmlNodeList对象nodeList。第5行通过doc对象的DocumentElement属性定义根节点对象root。第6行查找news节点列表。第7行使用foreach循环遍历访问节点列表。第8行使用ChildNodes属性获得news节点下的所有的子节点。第9行使用foreach循环遍历子节点的内容。第10行输出子节点包含的数据内容。
04 按快捷键Ctrl+F5运行程序,运行结果如图15-8所示。
图15-8 运行结果
15.2.6 创建新节点
XmlDocument具有用于所有节点类型的Create方法。为该方法提供节点的名称、节点的内容或节点的参数就可创建节点。表15-6列举了XmlDocument常用的创建节点的方法。
表15-6 XmlDocument常用的创建节点的方法
在创建新节点后,就可以用方法来给新创建的节点添加信息,将其插入到XML结构树中。下表15-7列出了这些常用的方法。
表15-7 向XML结构树中插入节点的方法
【实例15-5】创建新节点
本实例实现动态创建XML数据节点,用户在文本空中输入节点的信息,单击“创建”按钮,完成节点的创建,具体实现步骤如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例15-5”。
02 在该网站中创建一个XMLFile.xml文件,文件中的内容与“实例15-1”中XMLFile.xml文件相同。
03 双击网站的目录下的Default.aspx文件,进入“视图编辑”界面,从工具箱中拖动一个Label控件、一个Button控件和6个TextBox控件到“设计视图”。设计完成后的界面如图15-9所示。
图15-9 设计界面
04 单击网站目录下的Default.aspx.cs文件,在该文件中编写如下逻辑代码:
上面的代码中第1行定义处理按钮控件Button1单击事件Click的方法。第2行定义XmlDocument对象doc。第3行使用doc对象把XMLFile.xml文件加载到内存中。第4行和第9行设置文件的标记和从用户输入文本框的内容。第10行通过拼接字符串将添加的XML文档内容赋给字符串对象str4。第11行定义XmlDocument对象doc1。第12行调用doc1的LoadXml方法将str4作为参数读入XMLFile.xml文件中。第13行调用doc对象的ImportNode方法将doc1对象的最后一根子节点导入doc对象加载的文档中并赋给一个创建的节点对象node。第14行调用doc对象根节点添加子节点的方法AppendChild添加node节点。第15行把修改后doc对象保存到XMLFile.xml。第14行在标签控件上显示创建成功的提示。
05 按快捷键Ctrl+F5运行程序,如图15-10所示。用户输入新节点的内容,单击“创建”按钮,显示创建节点成功的提示。
图15-10 运行结果1
06 用右键单击XMLFile.xml文件,在弹出的菜单中选择“在浏览器中查看”命令。运行后的效果如图15-11所示。
图15-11 运行结果2
15.2.7 修改XML文档
在.NET4.5框架下,使用DOM开发人员可以有多种方法来修改XML文档的节点、内容和值。常用的修改XML文档的方法如下:
● 使用XmlNode.Value方法更改节点值。
● 通过用新节点替换节点来修改全部节点集。这可使用XmlNode.InnerXml属性来完成。
● 使用XmlNode.ReplaceChild方法用新节点替换现有节点。
● 使用XmlCharacterData.AppendData方法、XmlCharacterData.InsertData方法或XmlCharacterData.ReplaceData方法将附加字符添加到从XmlCharacter类继承的节点。
● 对从XmlCharacterData继承的节点类型使用DeleteData方法移除某个范围的字符来修改内容。
● 使用SetAttribute方法更新属性值。如果不存在属性,SetAttribute创建一个新属性;如果存在属性,则更新属性值。
【实例15-6】修改XML节点
本实例实现修改XML文件的节点。当用户从下拉列表中选择要修改的节点,然后在文本框中输入要更新的新节点名称,单击“修改”按钮,完成修改文件操作,具体实现步骤如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例15-6”。
02 在该网站中创建一个XMLFile.xml文件,文件中的内容与本章“实例15-1”中的XMLFile.xml文件相同。
03 在网站根目录下创建一个名为Default.aspx的窗体文件,单击该文件,进入“视图编辑”界面,从工具箱中拖动一个GridView控件、一个DropDownList控件、一个TextBox控件和一个Button控件到“设计视图”,设计后的界面如图15-12所示。
图15-12 设计后的界面
04 单击网站目录下的Default.aspx.cs文件,在该文件中编写如下逻辑代码:
上面的代码中第1行定义处理页面Page加载事件Load的方法。第2行判断如果当前加载的页面不是回传页面,则第3行创建DataSet对象ds。第4行调用ds对象的ReadXml方法读取XMLFile.xml文件。第5行将ds作为列表控件GridView1的数据源。第6行绑定数据到GridView1控件。第7行将ds作为下拉列表控件DropDownList1的数据源。第8行绑定显示在DropDownList1的是news_title标记中的内容。第9行绑定数据到DropDownList1控件。
第12行定义处理按钮控件Button1单击事件Click的方法。第13行创建XmlDocument对象doc。第14行加载XMLFile.xml文件。第15行获取XML文件中xinwen节点下所有子节点集合。第16行循环变量所有节点集合中的子节点。第17行获取每一个节点元素。第18行判断如果节点是news。第19行获取basic节点下所有子节点的集合。第20行遍历所有子节点集合中的节点。第21行获取每一个节点元素。第22行判断如果节点元素的名称是news_title,同时节点元素的内容和下拉列表控件DropDownList1中用户选择的值相同。则第23行将用户输入文本框的新节点值赋给要修改的节点元素。第24行在页面显示修改成功的对话框。第29行把修改后doc对象保存到XMLFile.xml。第30行跳转页面到Default.aspx。
05 按快捷键Ctrl+F5运行程序,如图15-13所示。用户选择要修改的节点,输入新节点名称,单击“修改”按钮。修改文档后列表中显示了新的节点,如图15-14所示。
图15-13 运行结果1
图15-14 运行结果2
15.2.8 删除XML文档的节点、属性和内容
当文档对象模型DOM在内存中之后,就可以删除XML中的节点,或删除特定节点类型中的内容和值。
(1)删除节点
如果要从DOM中移除节点,可以使用RemoveChild方法移除特定节点。移除节点时,此方法移除属于所移除节点的子树。如果要从DOM中移除多个节点,可以使用RemoveAll方法移除当前节点的所有子级和属性。
如果使用XmlNamedNodeMap,则可以使用RemoveNamedItem方法移除节点。
(2)删除属性集合中的属性
可以使用XmlAttributeCollection.Remove方法移除特定属性;也可以使用XmlAttributeCollection.RemoveAll方法移除集合中的所有属性,使元素不具有任何属性;或者使用XmlAttributeCollection.RemoveAt方法移除属性集合中的属性(通过使用其索引号)。
(3)删除节点属性
使用XmlElement.RemoveAllAttributes移除属性集合;使用XmlElement.RemoveAttribute方法按名称移除集合中的单个属性;使用XmlElement.RemoveAttributeAt按索引号移除集合中的单个属性。
(4)删除节点内容
可以使用DeleteData方法移除字符,此方法从节点中移除某个范围的字符。如果要完全移除内容,则移除包含此内容的节点。如果要保留节点,但节点内容不正确,则修改内容。
【实例15-7】删除XML节点
本实例实现删除XML文件的节点。当用户在下拉列表中选择要删除的节点后,单击“删除”按钮,即可完成删除节点的操作,具体实现步骤如下。
01 启动Visual Studio 2012,创键一个ASP.NET Web空应用程序,命名为“实例15-7”。
02 在该网站中创建一个XMLFile.xml文件,文件中的内容与本章“实例15-2”中的XMLFile.xml文件相同。
03 在网站根目录下创建一个名为Default.aspx的窗体文件,单击该文件文件,进入“视图编辑”界面,从工具箱中拖动一个GridView控件、一个DropDownList控件、和一个Button控件到“设计视图”。
04 单击网站目录下的Default.aspx.cs文件,在该文件中编写关键逻辑代码如下:
上面的代码中第1行定义处理按钮控件Button1单击事件Click的方法。第2行创建XmlDocument对象doc。第3行加载XMLFile.xml文件。第4行声明XmlNodeList对象node。第5行定义调用doc对象的DocumentElement获得根节点对象root。第6行通过根节点对象root的SelectNodes获得news节点下用户选择的news_title子节点元素。第7行循环遍历用户选择的子节点元素下的所有子节点。第8行调用root对象的RemoveChild方法删除这些子节点内容。第10行显示删除成功对话框。第11行把商场数据后的doc对象保存到XMLFile.xml。
05 按快捷键Ctrl+F5运行程序,效果如图15-15所示。用户选择要删除的节点,单击“删除”按钮。删除节点后的列表中显示选择的节点已经被成功地删除,如图15-16所示。
图15-15 运行结果1
图15-16 运行结果2