27.2 使用DOM

W3C的文档对象模型(Document Object Model,DOM)是一个使程序和脚本有能力动态地访问和更新文档的内容、结构以及样式的接口,与平台和语言无关。DOM被分为3种类型,如下所示。

❑核心DOM:用于任何结构化文档的标准模型;

❑XML DOM:用于XML文档的标准模型;

❑HTML DOM:用于HTML文档的标准模型。

本章要使用的就是XML DOM,因为我们要操作的文档类型是XML。这里要详细讨论的也是XML DOM,它是用于获取、更改、添加或删除XML元素的标准。XML文档中的每个组成部分都是一个节点。

DOM是这样规定的:

❑整个文档是一个文档节点;

❑每个XML标签是一个元素节点;

❑包含在XML元素中的文本是文本节点;

❑每一个XML属性是一个属性节点;

❑注释属于注释节点。

下面是一个示例XML文档,如代码清单27-1所示。

代码清单27-1 示例XML文档


<?xml version="1.0"encoding="UTF-8"?>

<books>

<book category=“计算机”>

<title lang=“中文”>C Sharp 4.0程序设计</title>

<author>姜晓东</author>

<year>2010</year>

</book>

<book category=“小说”>

<title lang=“英文”>哈利波特与魔法石</title>

<author>J K.Rowling</author>

<year>1977</year>

</book>

</books>


如果使用图形表示,上述XML代码可以用图27-1表示,注意,这里仅包含了一个<book>节点。

27.2 使用DOM - 图1

图 27-1 DOM树

接下来,我们使用这些类来对代码清单27-1的XML文档进行节点和属性的增删改查处理,以了解XML文档的基本操作。将上述XML文档保存于c:\books.xml,如果下文没有说明,均指该xml文档。具体代码如代码清单27-2所示。

代码清单27-2 对XML文档元素进行增删改查


using System;

using System.Xml;

namespace ProgrammingCSharp4

{

class XmlHandleSample

{

public static void Main()

{

try

{

//声明一个XmlDocument对象,代表xml文档

XmlDocument doc=new XmlDocument();

//通过路径将xml文档的内容加载到doc对象中

doc.Load(@"c:\books.xml");

//使用xpath表达式查询出books节点,它是根节点

XmlNode root=doc.SelectSingleNode("books");

//声明并初始化一个新的XmlElement对象,表示book节点

XmlElement newBookNode=doc.CreateElement("book");

//为book节点创建一个名为category的属性,并赋值

newBookNode.SetAttribute("category",“计算机”);

//创建一个名为title的节点,它是book节点的子节点

XmlElement newTitleNode=doc.CreateElement("title");

//为title节点指定文字内容

newTitleNode.InnerText=“计算机程序设计艺术(第一卷,第三版)”;

//为title子节点新增属性,并赋值

newTitleNode.SetAttribute("lang",“英文”);

//将title节点添加到book节点

newBookNode.AppendChild(newTitleNode);

//和新增title节点类似,此处省略

XmlElement newAuthorNode=doc.CreateElement("author");

newAuthorNode.InnerText=“高德纳”;

newBookNode.AppendChild(newAuthorNode);

XmlElement newYearNode=doc.CreateElement("year");

newYearNode.InnerText="1997";

newBookNode.AppendChild(newYearNode);

//将新增的book节点添加到根节点

root.AppendChild(newBookNode);

//保存新的xml文档到新文件

doc.Save(@"c:\books2.xml");

Console.WriteLine(“新增节点成功完成。”);

Console.WriteLine(“任意键继续修改一个节点……”);

Console.ReadKey();

//重新初始化doc对象

doc=new XmlDocument();

//并加载books2.xml,这是新增了一个节点的xml文档

doc.Load(@"c:\books2.xml");

//使用xpath,查询出具有category属性,且值

//为“计算机”的book节点,返回一个XmlNodeList集合对象

XmlNodeList nodes=doc.SelectNodes(“//book[@category='计算机']”);

//遍历返回的节点集合

foreach(XmlNode node in nodes)

{

XmlElement current=(XmlElement)node;

//修改属性值

current.SetAttribute("category","computer");

XmlElement author=current.SelectSingleNode("author")as XmlElement;

//修改节点的值

if(author.InnerText.Equals(“姜晓东”))

{

author.InnerText="Jiang Xiao Dong";

}

else if(author.InnerText.Equals(“高德纳”))

{

author.InnerText="Donald Ervin Knuth";

}

}

doc.Save(@"c:\books3.xml");

Console.WriteLine(“修改节点成功完成。”);

Console.WriteLine(“任意键继续删除一个节点……”);

Console.ReadKey();

doc=new XmlDocument();

doc.Load(@"c:\books3.xml");

//查询出新增的节点

XmlNode bookNode=doc.SelectSingleNode("//book[author='Donald Ervin Knuth']");

//移除当前节点

bookNode.ParentNode.RemoveChild(bookNode);

doc.Save(@"c:\books4.xml");

Console.WriteLine(“删除节点成功完成。”);

Console.WriteLine(“任意键退出……”);

Console.ReadKey();

}

catch(System.Exception)

{

Console.WriteLine(“处理过程出错,请检查。”);

throw;

}

}

}

}


上述代码运行结果为:


新增节点成功完成。

任意键继续修改一个节点……

修改节点成功完成。

任意键继续删除一个节点……

删除节点成功完成。

任意键退出……


代码清单27-2 先在代码清单27-1所示的XML文档的基础上新增了一个book节点,并另存为c:\books2.xml,其内容如代码清单27-3所示。

代码清单27-3 books2.xml

27.2 使用DOM - 图2

然后重新加载books2.xml文档,将“category=‘计算机’”的book节点查找出来。这里使用的是xpath查询表达式,可见查询的结果将会有两个book节点。然后将这些book节点的category的属性值改为computer,并将各自的中文作者名修改为英文,最终修改结果保存为c:\books3.xml,其内容如代码清单27-4所示。

代码清单27-4 books3.xml

27.2 使用DOM - 图3

最后,以books3.xml为基础,将开始新增的book节点删除掉,并把结果保存为c:\books4.xml。其内容如代码清单27-5所示。

代码清单27-5 books4.xml


<?xml version="1.0"encoding="UTF-8"?>

<books>

<book category="computer">

<title lang=“中文”>C Sharp 4.0程序设计</title>

<author>Jiang Xiao Dong</author>

<year>2010</year>

</book>

<book category=“小说”>

<title lang=“英文”>哈利波特与魔法石</title>

<author>J K.Rowling</author>

<year>1977</year>

</book>

</books>