XML文件操作指南
一、XML简介
XML的全名是eXtensible Markup Language(可以扩展的标记语言),它的语法类似HTML,都是用标签来描述数据。HTML的标签是固定的,我们只能使用、不能修改; XML则不同,它没有预先定义好的标签可以使用,而是依据设计上的需要,自行定义标签。XML是一个元语言,根据不同的行业和语义,由它可以派生出许许多多的协议和规范。
XML主要提供了两种对象模型。分别是:
(1)文档对象模型(DOM)类是XML文档的内存中表示形式。DOM 使你能够以编程方式读取、操作和修改XML文档。XmlReader类也读取XML,但它提供非缓存的只进、只读访问。这意味着使用 XmlReader无法编辑属性值或元素内容,或无法插入和移除节点。编辑是 DOM 的主要功能。XML数据在内存中表示是常见的结构化方法,尽管实际的XML数据在文件中时或从另一个对象传入时以线性方式存储。
(2)架构对象模型(SOM)在System.Xml.Schema命名空间中提供了一组类,该命名空间对应于并完全遵守WWW 联合会(W3C) XML Schema Recommendation(XML架构建议)。这些类使你可以从文件中读取架构,或以编程方式在内存中创建可以编译和验证或可以写入到文件中的架构。
本文我们将以文档对象模型(DOM)为基础展开介绍。
二、XML的命名空间和相关类概览
.Net框架为我们提供了以下一些命名空间:System.Xml、System.Xml.Schema、System.Xml.Serialization、System.Xml.Xpath以及 System.Xml.Xsl来包容和XML操作相关的类。本文中我们将主要讨论System.Xml命名空间,其他的相关内容请读者自行查阅相关资料。
System.Xml命名空间包含各种各样的XML类,这些类可使用读取器、编写器和符合WWW 联合会 (W3C) DOM 要求的组件来对 XML 数据进行分析、验证和操作。以下列表包含XML命名空间中主要的类:
XmlNode 是重要的抽象类,DOM树中的每个节点都应是它的派出。
XmlDocument类 实现 W3C 文档对象模型级别1核心以及核心DOM级别2。
XmlTextReader类 提供对XML数据的快速、非缓存和只进的读取访问。
XmlNodeReader类 为给定的DOM节点子树提供 XmlReader。
XmlValidatingReader类 提供DTD、XDR和XSD架构验证。
XmlTextWriter类 提供生成XML的快速、只进的方式。
XmlDataDocument类 提供可与数据集关联的XmlDocument的实现。可通过数据集的关系表示形式或XmlDataDocument的树表示形式同时查看和操作结构化XML。
XPathDocument类 为XSLT提供了一种进行 XML 文档处理的快速和高性能的缓存。
XPathNavigator类 为用于存储的W3C XPath 1.0数据模型提供了一种光标样式模型以便于浏览。
XslTransform类是与W
3C XSLT 1.0规范兼容的XSLT处理器,用于转换XML文档。
XmlSchema 对象模型类提供一组可进行浏览的类,这些类直接反映W3C XSD规范。它们提供以编程方式创建XSD架构的功能。
XmlSchemaCollection类 提供XDR和XSD架构库。这些缓存在内存中的架构为XmlValidatingReader提供快速的、分析时验证XmlReader类。
三、XML文档对象模型(DOM)
.NET仅仅支持XML DOM模式,而不支持SAX模式。文档对象模型(DOM)类是XML文档的内存中表示形式,XML数据在内存中的表示是结构化的,一般使用树结构表示DOM对象模型。为了对DOM内存结构有更直观的认识,先看下例XML数据在内存的构造。
<xml version="1.0">
<book>
<author>江新</author>
<price>40</price>
</book>
1.读取XML数据
XML DOM模式提供多种方式读取XML数据,如从流、URL、文本读取器或XmlReader中读取。Load方法将文档读入内存中,并包含可用于从每个不同的的格式中获取数据的重载方法。如下段代码演示了多XmlReader读取器中读取XML数据。
// Create the validating reader and specify DTD validation.
txtReader = new XmlTextReader(filename);
reader = new XmlValidatingReader(txtReader);
reader.ValidationType = ValidationType.DTD;
// Set a handler to handle validation errors.
reader.ValidationEventHandler += eventHandler;
// Pass the validating reader to the XML document.
// Validation fails due to an undefined attribute, but the
// data is still loaded into the document.
XmlDocument doc = new XmlDocument();
doc.Load(reader);
Console.WriteLine(doc.OuterXml);
另外,还有一个简便的LoadXML方法,它直接从字符串中读取XML,如:
//新建XmlDocument对象。
XmlDocument doc = new XmlDocument();
//读取XML数据。
doc.LoadXml("<book><author>碧清</author><price>40</priec></book>");
2.访问DOM中的属性
XML文档中另一重要特性是属性,它表示元素的某种特性。下面我们学习如何访问到元素的属性。在DOM模式中,如当前节点是元素时,可先使用HasAttribute方法检测是否存在属性,如存在,可使用XmlElement.Attributes属性获取包含该元素所有属性的集合。一般情况下,可按如下步骤访问元素的属性:
//获取book节点元素的属性集合。
XmlAttributeCollection attrs = myxml.DocumentElement.
SelectSingleNode(“//book”).Attributes;
//从属性集合中提取属性ID。
XmlAttribute attr = attrs["ID"];
//获取属性ID的值。
string id = atrr.Value;
3.在DOM中创建新节点
可以
通过在DOM树中插入新的节点来为XML文档新添新的元素。XmlDoument类中提供了创建所有类型节点的方法,如CreateElement、CreateTextNode等。创建了新节点后,可使用几种方法将其插入到DOM树中。
如下段代码新建一个元素节点:
//新建一个Element节点,将插入到book节点的子节点中。
XmlElement elem = doc.CreateElement("ISDN");
//新建一个Text节点,将其作为ISDN的值。
XmlText text = doc.CreateTextNode("CN94-0000/TP");
插入节点到DOM树中的方法共有如下几种:
InsertBefore:表示插入到引用节点之前。如,在位置5插入新节点:
XmlNode refChild=node.ChildNodes[4];
Node.InsertBefore(newChild,refChild);
InsertAfter:表示插入引用节点之后。
AppendChild:表示将节点添加到给定节点的子节点列表的未尾。
PrependChild:表示将节点添加到给定节点的子节点列表的开头。
Append:表示将XmlAttribute节点追加到与元素关联的属性集合的未尾。
下段代码将上面创建两个节点插入到book节点的子节点中:
//将elem节点插入到book节点的最后一个子节点处。
doc.DocumentElement.AppendChild(elem);
//将text节点添加作为elem节点的值。
doc.DocumentElement.LastChild.AppendChild(text);
4.在DOM中删除节点
在DOM中删除节点,可使用RemoveChild方法,如从DOM中删除多个节点可直接调用RemoveAll方法,它将删除当前节点的所有子级和属性。
如:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'>" +
"<title>Pride And Prejudice</title>" +
"</book>");
XmlNode root = doc.DocumentElement;
//删除title元素节点。
root.RemoveChild(root.FirstChild);
如果仅仅删除元素节点的属性,可使用以下三种方法:
XmlAttributeCollection.Remove:删除特定属性。
XmlAttributeCollection.RemoveAll:删除集合中的所有属性。
XmlAttributeCollection.RemoveAt:通过索引号来删除集合中某属性。
如:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'>" +
"<title>Pride And Prejudice</title>" +
"</book>");
XmlAttributeCollection attrColl = doc.DocumentElement.Attributes;
//删除属性genre。
attrColl.Remove(attrColl["genre"]);
5.保存XML文档
当应用程序对XML文档进行了有效的修改后,需要将内存中的内容保存到磁盘的XML文件中。保存XML文档很简单,调用Save方法即可。
下段程序代码
演示了Save方法的使用:
using System;
using System.Xml;
public class Sample {
public static void Main() {
// Create the XmlDocument.
XmlDocument doc = new XmlDocument();
doc.LoadXml("<item><name>wrench</name></item>");
// Add a price element.
XmlElement newElem = doc.CreateElement("price");
newElem.InnerText = "10.95";
doc.DocumentElement.AppendChild(newElem);
// Save the document to a file and auto-indent the output.
XmlTextWriter writer = new XmlTextWriter("l",null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);
}
}
四、使用XmlReader阅读器访问XML文档
XmlReader是一个抽象类,它提供非缓存的、只进只读访问XML文档的功能。XmlReader立刻器工作原理类似于我们的桌面应用程序从数据库中取出数据的原理。数据库服务返回一个游标对象,它包含所有查询结果集,并返回指向目标数据集的开始地址的引用。XmlReader阅读器的客户端收到一个指向阅读器实例的引用。该实例提取底层的数据流并把取出的数据呈现为一棵XML树。阅读器类提供只读、向前的游标,你可以用阅读器类提供的方法滚动游标遍历结果集中的每一条数据。
作为阅读器的抽象基类,它让开发人员能够自定义自己类型的阅读器,在.NET类库中,已为应用程序实现了三种类型的阅读器类,即XmlTextReader、XmlValidatingReader或者 XmlNodeReader类。
阅读器的主要功能是读XML文档的方法和属性。其类中的Read方法是一个基本的读XML文档的方法,
它以流形式读取XML文档中的节点(Node)。另外,类还提供了ReadString、ReadInnerXml、ReadOuterXml和ReadStartElement等更高级的读方法。除了提供读XML文档的方法外,XmlReader类还提供了MoveToAttribute、MoveToFirstAttribute、MoveToContent、MoveToFirstContent、MoveToElement以及 MoveToNextAttribute等具有导航功能的方法。
(一) 使用XmlReader阅读器
要想使用XMLReader阅读器,首先必须创建一个XmlReader派出类的实例对象,如:
XmlTextReader reader = new XmlTextReader(file)
使用一个文件流创建XmlTextReader阅读器。创建完一个阅读器对象后,可以作为XmlDocument.Load方法的参数使用(其访问XML文档方法在前面已介绍过);也可以直接使用阅读器读取文档结构内容,如下段代码演示了如何使用XmlTextReader阅读器读取XML文档:
// 创建一个XmlTextReader类使它指向目标XML文档
XmlTextReader reader = new XmlTextReader(file);
// 循环取出节点的文本并放入到StringWriter对象实例中
StringWriter writer = new StringWriter();
string tabPrefix = "";
while (reader.Read())
{
//输出开始标志,如果节点类型为元素
if (reader.NodeType == XmlNodeType.Element)
{
//根据元素所处节点的深度,加入reader.Depth个tab符,然后把元素名输出到<>中。
tabPrefix = new string('\t', reader.Depth);
writer.WriteLine("{0}<{1}>", tabPrefix, reader.Name);
}
else
{
//输出结束标志,如果节点类型为元素
if (reader.NodeType == XmlNodeType.EndElement)
{
tabPrefix = new string('\t', reader.Depth);
writer.WriteLine("{0}</{1}>", tabPrefix, reader.Name);
}
(二) XmlReader的属性
XmlReader类具有一些可以在读取时修改的属性,以及一些在读取开始后被更改时并不会使新设置影响读取的其他属性。下面我们对XmlReader属性做一下简要介绍。
writeline方法属于类 AttributeCount属性:当在派生类中被重写时,获取当前节点上的属性数。
BaseURI属性:当在派生类中被重写时,获取当前节点的基 URI。
CanResolveEntity属性:获取一个值,该值指示此读取器是否可以分析和解析实体。
Depth属性:当在派生类中被重写时,获取 XML 文档中当前节点的深度。
EOF属性:当在派生类中被重写时,获取一个值,该值指示此读取器是否定位在流的结尾。
HasAttributes属性:获取一个值,该值指示当前节点是否有任何属性。
HasValue属性:当在派生类中被重写时,获取一个值,该值指示当前节点是否可以具有Value。
IsDefault属性:当在派生类中被重写时,获取一个值,该值指示当前节点是否是从 DTD 或架构中定义的默认值生成的属性。
IsEmptyElement属性:当在派生类中被重写时,获取一个值,该值指示当前节点是否是一个空元素(例如 )。
Item属性:已重载。当在派生类中被重写时,获取此属性的值。 在 C# 中,该属性为 XmlReader 类的索引器。
(三)XmlReader常用方法
1.ReadInnerXml和ReadOuterXml方法
XmlReader提供了ReadInnerXml和ReadOuterXml方法读取元素和属性内容。ReadInnerXml将所有内容(包括标记)当做字符串读取,而ReadOuterXml读取表示该节点和所有它的子级的内容(包括标记)。
假设XML文档:
<node>
this <child id="123"/>
</node>
ReadInnerXml调用将返回this <child id="123"/>,而ReadOuterXml调用将返回<node> this <child id="123"/></node>。
2.Read方法
表示从流中读取下一个节点。通常用在循环中。如:
XmlTextReader rdr=new XmlTextReader("l");
while(rdr.Read())
{
….//依次读取各节点。
}
3.ReadAttributeValue方法
将属性值解析为一个或
多个 Text、EntityReference 或 EndEntity 节点。如:
//Create the reader.
reader = new XmlTextReader(xmlFrag, XmlNodeType.Element, context);
//Read the misc attribute. The attribute is parsed
//into multiple text and entity reference nodes.
reader.MoveToContent();
reader.MoveToAttribute("misc");
while (reader.ReadAttributeValue()){
if (reader.NodeType==XmlNodeType.EntityReference)
Console.WriteLine("{0} {1}", reader.NodeType, reader.Name);
else
Console.WriteLine("{0} {1}", reader.NodeType, reader.Value);
}
4.ReadString方法
将元素或文本节点的内容当做字符串读取。如:
//Load the reader with the XML file.
reader = new XmlTextReader("l");
//Parse the XML and display the text content of each of the elements.
while (reader.Read()){
if (reader.IsStartElement()){
if (reader.IsEmptyElement)
Console.WriteLine("<{0}/>", reader.Name);
else{
Console.Write("<{0}> ", reader.Name);
reader.Read(); //Read the start tag.
if (reader.IsStartElement()) //Handle nested elements.
Console.Write("\r\n<{0}>", reader.Name);
Console.WriteLine(reader.ReadString()); //Read the text content of the element.
}
}
5.其他方法
MoveToElement:移动到包含当前属性节点的元素。
MoveToFirstAttribute:移动到第一个属性。
MoveToNextAttribute:移动到下一个属性。
Skip:跳过当前节点的子级。
五、使用XmlWriter类写XML文档
XmlWriter 是定义用于编写 XML 的接口的抽象基类。XmlWriter 提供只进、只读、不缓存的 XML 流生成方法。更重要的是,XmlWriter在设计时就保证所有的XML数据都符合W3C XML 1.0推荐规范,你甚至不用担心忘记写闭标签,因为XmlWriter搞定一切。
像XmlReader抽象类一样,应用必须使用XmlWriter的一个派出类来创建实例,用户可以自定义自己的XmlWriter派出类,.Net类库中提供XmlTextWriter派出类。
(一) 使用XmlWriter
使用XmlWrite之前,必须新建一个XmlWriter抽象类的派出类实例,再使用XmlWrite的WriteXXX方法写入元素、属性和内容,最后使用Close方法关闭XML文档。
下段代码演示使用XmlWriter编写XML文档的例子:
// Open the XML writer (用默认的字符集)
XmlTextWriter xmlw = new XmlTextWriter(filename, null);
xmlw.Formatting = Formatting.Indented;
xmlw.WriteStartDocument();
xmlw.WriteStartElement("array");
foreach(string s in theArray)
{
xmlw.WriteStartElement("element")
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论