暂时先记下这几个问题:
1对于xml文件的读取(和其它对文件的操作一样要通过:server.mappath(XXX))
2要分清xml架构的特点,是树形的,可以看看数据结构相关资料
3要分清内容和值的区别,内容是当前节点包含的内容(content如:<name>kkcat</name>中的kkcat)值则不是,暂时还不清楚是什么意思
下面是一些我认为比较好的资料:
最少的先贴
转自: http://www.cnblogs.com/nosnowwolf/archive/2006/12/12/590191.html
在asp.net中读取XML文件信息的4种方法
<% @ Page Language="C#"%>
<html>
<body>
<h3><font face="Verdana">读取XML方法一</font></h3>
<from runat=server>
<asp:Xml id="xml1" DocumentSource="grade.xml" runat="server" />
</from>
</body>
</html>
方法二: 使用DOM技术
<% @ Page Language="C#"%>
<% @ Import Namespace="System.Xml"%>
<% @ Import Namespace="System.Xml.Xsl"%>
<html>
<script language="C#" runat="server">
void Page_Load(Object sender,EventArgs e)
{
XmlDocument doc=new XmlDocument();
doc.Load(Server.MapPath("grade.xml"));
xml1.Document=doc;
}
</script>
<body>
<h3><font face="Verdana">读取XML方法二</font></h3>
<from runat=server>
<asp:Xml id="xml1" runat="server" />
</from>
</body>
</html>
方法三 :使用DataSet对象
<% @ Page Language="C#"%>
<% @ Import Namespace="System.Data"%>
<% @ Import Namespace="System.Data.OleDb"%>
<script language="C#" runat="server">
void Page_Load(Object sender,EventArgs e)
{
DataSet objDataSet=new DataSet();
objDataSet.ReadXml(Server.MapPath("grade.xml"));
dgEmployees.DataSource=objDataSet.Tables["student"].DefaultView;
dgEmployees.DataBind();
}
</script>
<body>
<h3><font face="Verdana">读取XML方法三</font></h3>
<asp:DataGrid id="dgEmployees" runat="server" />
</body>
</html>
方法四 :按文本方式读取
<% @ Page Language="C#"%>
<% @ Import Namespace="System.Xml"%>
<html>
<script language="C#" runat="server">
private void Page_Load(Object sender,EventArgs e)
{
XmlTextReader objXMLReader=new XmlTextReader(Server.MapPath("grade.xml"));
string strNodeResult="";
XmlNodeType objNodeType;
while(objXMLReader.Read())
{
objNodeType =objXMLReader.NodeType;
swith(objNodeType)
{
case XmlNodeType.XmlDeclaration:
//读取XML文件头
strNodeResult+="XML Declaration:<b>"+objXMLReader.Name+""+objXMLReader.Value+"</b><br/>";
break;
case XmlNodeType.Element:
//读取标签
strNodeResult+="Element:<b>"+objXMLReader.Name+"</b><br/>";
break;
case XmlNodeType.Text:
//读取值
strNodeResult+=" -Value:<b>"+objXMLReader.Value+"</b><br/>";
break;
}
//判断该节点是否有属性
if(objXMLReader.AttributeCount>0)
{ //用循环判断完所有节点
while(objXMLReader.MoveToNextAttibute)
{ //取标签和值
strNodeResult+=" -Attribute:<b>"+objXMLReader.Name+"</b> value:<b>"+objXMLReader.Value+"</b><br/>";
}
}
LblFile.Text=strNodeResult;
}
}
</script>
<body>
<h3><font face="Verdana">读取XML方法四</font></h3>
<from runat=server>
<asp:label id="LblFile" runat="server" />
</from>
</body>
</html>
这个比较清爽比较好理解(我这么认为)
转自: http://ltp.cnblogs.com/archive/2005/12/02/289613.html
string filename=Server.MapPath("/") + @"WebApplication1\web.config";
XmlDocument xmldoc= new XmlDocument();
xmldoc.Load(filename);
XmlNodeList topM=xmldoc.DocumentElement.ChildNodes;
foreach(XmlElement element in topM)
{
if(element.Name.ToLower()=="appsettings")
{
XmlNodeList nodelist=element.ChildNodes;
{
//DropDownList1.Items.Clear();
{
//DropDownList1.Items.Add(el.Attributes["key"].InnerXml);
//this.TextBox2.Text=el.Attributes["key"].InnerText;
this.TextBox2.Text=el.Attributes["key"].Value;
this.Label1.Text=el.Attributes["value"].Value;
}
}
}
}
xmldoc.Save(filename);
在某节点下增加一个元素,并设置值:if(element.Name.ToLower()=="appsettings")
{XmlElement elem =xmldoc.CreateElement("add");
element.AppendChild(elem);
elem.InnerText="ltp";xmldoc.Save(filename);
}效果:<appSettings>
<add key="密码" value="admin" />
<add>ltp</add>
</appSettings>在某节点下增加一个元素,并增加两个属性:if(element.Name.ToLower()=="appsettings")
{XmlElement elem =xmldoc.CreateElement("add");
element.AppendChild(elem);
XmlAttribute xa=xmldoc.CreateAttribute("key");
xa.Value="ltp";XmlAttribute xa2=xmldoc.CreateAttribute("value");
xa2.Value="first";elem.SetAttributeNode(xa);
elem.SetAttributeNode(xa2);
xmldoc.Save(filename);
}效果:<appSettings>
<add key="密码" value="admin" />
<add key="ltp" value="first" />
</appSettings>//添加空元素:XmlNode node=doc.CreateElement(groupname);
node.InnerText="";
doc.LastChild.AppendChild(node);doc.Save(xmlfile);删除一个节点元素string itemname=this.listBox1.SelectedItem.ToString();
this.listBox1.Items.Remove(this.listBox1.SelectedItem);//begin del xmlfile
XmlDocument doc=new XmlDocument();
doc.Load(xmlfile);
XmlNodeList topM=doc.DocumentElement.ChildNodes;
foreach(XmlElement element in topM)
{
if(element.Name==this.comboBox1.Text)
{
//得到该节点的子节点
XmlNodeList nodelist=element.ChildNodes;
foreach(XmlElement el in nodelist)//读元素值
{
if(el.Attributes["key"].Value==itemname)
{
element.RemoveChild(el);
}
}//循环元素
}//得到组}//循环组
doc.Save(xmlfile); //一定要保存一下,否则不起作用//筛选数据private void Reader_Xml(string pathFlie)
{
XmlDocument Xmldoc=new XmlDocument();
Xmldoc.Load(pathFlie);
XmlNodeList Record1=Xmldoc.DocumentElement.SelectNodes(Code[@id='1'])
int f=0;
foreach(XmlNode xnode in Record1)
{}
}
这个方便查询
转自: http://www.cnblogs.com/Dragon-China/archive/2007/05/29/764081.html
之所以要引入XPath的概念,目的就是为了在匹配XML文档结构树时能够准确地找到某一个节点元素。可以把XPath比作文件管理路径:通过文件管理路径,可以按照一定的规则查找到所需要的文件;同样,依据XPath所制定的规则,也可以很方便地找到XML结构文档树中的任何一个节点.不过,由于XPath可应用于不止一个的标准,因此W3C将其独立出来作为XSLT的配套标准颁布,它是XSLT以及我们后面要讲到的XPointer的重要组成部分。
在介绍XPath的匹配规则之前,我们先来看一些有关XPath的基本概念。
首先要说的是XPath数据类型。XPath可分为四种数据类型:
- 节点集(node-set)
节点集是通过路径匹配返回的符合条件的一组节点的集合。其它类型的数据不能转换为节点集。- 布尔值(boolean)
由函数或布尔表达式返回的条件匹配值,与一般语言中的布尔值相同,有true和false两个值。布尔值可以和数值类型、字符串类型相互转换。- 字符串(string)
字符串即包含一系列字符的集合,XPath中提供了一系列的字符串函数。字符串可与数值类型、布尔值类型的数据相互转换。- 数值(number)
在XPath 中数值为浮点数,可以是双精度64位浮点数。另外包括一些数值的特殊描述,如非数值NaN(Not-a-Number)、正无穷大infinity、负无 穷大-infinity、正负0等等。number的整数值可以通过函数取得,另外,数值也可以和布尔类型、字符串类型相互转换。其中后三种数据类型与其它编程语言中相应的数据类型差不多,只是第一种数据类型是XML文档树的特有产物。
另外,由于XPath包含的是对文档结构树的一系列操作,因此搞清楚XPath节点类型也是很必要的。回忆一下第二章中讲到的XML文档的逻辑结构,一个XML文件可以包含元素、CDATA、注释、处理指令等逻辑要素,其中元素还可以包含属性,并可以利用属性来定义命名空间。相应地,在XPath中,将节点划分为七种节点类型:
- 根节点(Root Node)
根节点是一棵树的最上层,根节点是唯一的。树上其它所有元素节点都是它的子节点或后代节点。对根节点的处理机制与其它节点相同。在XSLT中对树的匹配总是先从根节点开始。- 元素节点(Element Nodes)
元素节点对应于文档中的每一个元素,一个元素节点的子节点可以是元素节点、注释节点、处理指令节点和文本节点。可以为元素节点定义一个唯一的标识id。
元素节点都可以有扩展名,它是由两部分组成的:一部分是命名空间URI,另一部分是本地的命名。- 文本节点(Text Nodes)
文本节点包含了一组字符数据,即CDATA中包含的字符。任何一个文本节点都不会有紧邻的兄弟文本节点,而且文本节点没有扩展名。- 属性节点(Attribute Nodes)
每 一个元素节点有一个相关联的属性节点集合,元素是每个属性节点的父节点,但属性节点却不是其父元素的子节点。这就是说,通过查找元素的子节点可以匹配出元 素的属性节点,但反过来不成立,只是单向的。再有,元素的属性节点没有共享性,也就是说不同的元素节点不共有同一个属性节点。
对缺省属性的处理等同于定义了的属性。如果一个属性是在DTD声明的,但声明为#IMPLIED,而该属性没有在元素中定义,则该元素的属性节点集中不包含该属性。
此外,与属性相对应的属性节点都没有命名空间的声明。命名空间属性对应着另一种类型的节点。- 命名空间节点(Namespace Nodes)
每一个元素节点都有一个相关的命名空间节点集。在XML文档中,命名空间是通过保留属性声明的,因此,在XPath中,该类节点与属性节点极为相似,它们与父元素之间的关系是单向的,并且不具有共享性。- 处理指令节点(Processing Instruction Nodes)
处理指令节点对应于XML文档中的每一条处理指令。它也有扩展名,扩展名的本地命名指向处理对象,而命名空间部分为空。- 注释节点(Comment Nodes)
注释节点对应于文档中的注释。
下面,我们来构造一棵XML文档树,作为后面举例的依托:
<A id="a1">
<B id="b1">
<C id="c1">
<B name="b"/>
<D id="d1"/>
<E id="e1"/>
<E id="e2"/>
</C>
</B>
<B id="b2"/>
<C id="c2">
<B/>
<D id="d2"/>
<F/>
</C>
<E/>
</A>现在,我们就来介绍一些XPath中节点匹配的基本方法。
条件匹配就是利用一些函数的运算结果的布尔值来匹配符合条件的节点。常用于条件匹配的函数有四大类:节点函数、字符串函数、数值函 数、布尔函数。例如前面提到的last()、position()等等。这些功能函数可以帮助我们精确寻找需要的节点。
- 路径匹配
路径匹配与文件路径的表示相仿,比较好理解。有以下几个符号:
符 号 含 义 举 例 匹配结果 / 指示节点路径 /A/C/D 节点"A"的子节点"C"的子节点"D",即id值为d2的D节点 / 根节点 // 所有路径以"//"后指定的子路径结尾的元素 //E 所有E元素,结果是所有三个E元素 //C/E 所有父节点为C的E元素,结果是id值为e1和e2的两个E元素 * 路径的通配符 /A/B/C/* A元素→B元素→C元素下的所有子元素,即name值为b的B元素、id值为d1的D元素和id值为e1和e2的两个E元素 /*/*/D 上面有两级节点的D元素,匹配结果是id值为d2的D元素 //* 所有的元素 | 逻辑或 //B | //C 所有B元素和C元素
- 位置匹配
对于每一个元素,它的各个子元素是有序的。如:
举 例 含 义 匹配结果 /A/B/C[1] A元素→B元素→C元素的第一个子元素 name值为b的B元素 /A/B/C[last()] A元素→B元素→C元素的最后一个子元素 id值为e2的E元素 /A/B/C[position()>1] A元素→B元素→C元素之下的位置号大于1的元素 id值为d1的D元素和两个具有id值的E元素
- 属性及属性
在XPath中可以利用属性及属性值来匹配元素,要注意的是,元素的属性名前要有"@"前缀。例如:
举 例 含 义 匹配结果 //B[@id] 所有具有属性id的B元素 id值为b1和b2的两个B元素 //B[@*] 所有具有属性的B元素 两个具有id属性的B元素和一个具有name属性B元素 //B[not(@*)] 所有不具有属性的B元素 A元素→C元素下的B元素 //B[@id="b1"] id值为b1的B元素 A元素下的B元素
- 亲属关系匹配
XML文档可归结为树型结构,因此任何一个节点都不是孤立的。通常我们把节点之间的归属关系归结为一种亲属关系,如父亲、孩子、祖先、后代、兄弟等等。在对元素进行匹配时,同样可以用到这些概念。例如:
举 例 含 义 匹配结果 //E/parent::* 所有E节点的父节点元素 id值为a1的A元素和id值为c1的C元素 //F/ancestor::* 所有F元素的祖先节点元素 id值为a1的A元素和id值为c2的C元素 /A/child::* A的子元素 id值为b1、b2的B元素,id值为c2的C元素,以及没有任何属性的E元素 /A/descendant::* A的所有后代元素 除A元素以外的所有其它元素 //F/self::* 所有F的自身元素 F元素本身 //F/ancestor-or-self::* 所有F元素及它的祖先节点元素 F元素、F元素的父节点C元素和A元素 /A/C/descendant-or-self::* 所有A元素→C元素及它们的后代元素 id值为c2的C元素、该元素的子元素B、D、F元素 /A/C/following-sibling::* A元素→C元素的紧邻的后序所有兄弟节点元素 没有任何属性的E元素 /A/C/preceding-sibling::* A元素→C元素的紧邻的前面所有兄弟节点元素 id值为b1和b2的两个B元素 /A/B/C/following::* A元素→B元素→C元素的后序的所有元素 id为b2的B元素、无属性的C元素、无属性的B元素、id为d2的D元素、无属性的F元素、无属性的E元素。 /A/C/preceding::* A元素→C元素的前面的所有元素 id为b2的B元素、id为e2的E元素、id为e1的E元素、id为d1的D元素、name为b的B元素、id为c1的C元素、id为b1的B元素
- 条件匹配
函数及功能
作用count()功能
统计计数,返回符合条件的节点的个数number()功能
将属性的值中的文本转换为数值substring() 功能
语法:substring(value, start, length)
截取字符串sum()功能
求和
这些功能只是XPath语法中的一部分,还有大量的功能函数没有介绍,而且目前XPath的语法仍然在不断发展中。通过这些函数我们可以实现更加复杂的查询和操作。
以上这些匹配方法中,用得最多的还要数路径匹配。依靠给出相对于当前路径的子路径来定位节点的。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();//建立文档对象
try
{
doc.Load("http://www.cnblogs.com/myOrder.xml");
XmlNode root = doc.DocumentElement;//获取文档的根节点
XmlNode temp;
temp = root.SelectSingleNode("姓名");
Console.WriteLine("(查找1)" + temp);
temp = root.SelectSingleNode("定购人信息/姓名");
Console.WriteLine("(查找2)" + temp.Name+":"+temp.InnerText);
temp = root.SelectSingleNode("订货信息/商品/品名");
Console.WriteLine("(查找3)" + temp.Name + ":" + temp.InnerText);
XmlNodeList templist = root.SelectNodes("订货信息/商品/品名");
Console.WriteLine("(查找4)");
foreach (XmlNode nodeinlist in templist)
{
Console.WriteLine(nodeinlist.Name + ":" + nodeinlist.InnerText);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();//辅助代码,用于保留控制台窗口
}
}
}
下面仅供参考:namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();//建立文档对象
try
{
doc.Load("http://www.cnblogs.com/myOrder.xml");
//在xmlDocument对象中搜索元素
Console.WriteLine("");
XmlNodeList myNodeList = doc.GetElementsByTagName("品名");
for (int i = 0; i < myNodeList;i++ )
{
Console.WriteLine(myNodeList[i].Name+":"+myNodeList[i].InnerText);
}
//在xmlElement对象中搜索元素
Console.WriteLine("在xmlElement对象中搜索元素");
XmlElement myElement = doc.DocumentElement;
myElement = (XmlElement)myElement.LastChild;
myNodeList = myElement.GetElementsByTagName("品名");
for (int i = 0; i < myNodeList; i++)
{
Console.WriteLine(myNodeList[i].Name + ":" + myNodeList[i].InnerText);}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();//辅助代码,用于保留控制台窗口
}
}
}
转自:http://bbs.ibox.com.cn/Message/2104/2103812.html
一、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类是与W3C 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("data.xml",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属性做一下简要介绍。
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("book.xml");
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("elems.xml");
//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");
xmlw.WriteAttributeString("value", s);
xmlw.WriteEndElement();
}
xmlw.WriteEndDocument();
// Close the writer
xmlw.Close();
(二) XmlWriter类的属性
XmlWriter类提供了如下属性:
WriteState属性:当在派生类中被重写时,获取编写器的状态。
XmlLang属性:当在派生类中被重写时,获取表示当前 xml:space 范围的 XmlSpace。
XmlSpace属性:当在派生类中被重写时,获取当前的 xml:lang 范围。
(三) XmlWriter类常用方法
1.WriteXXX方法
这是一系列写操作的方法,主要有:
WriteBase64方法:将指定的二进制字节编码为 Base64 并写出结果文本。
WriteBinHex方法:将指定的二进制字节编码为 BinHex 并写出结果文本。
WriteCData方法:写出包含指定文本的 <![CDATA[...]]> 块。
WriteCharEntity方法:为指定的 Unicode 字符值强制生成字符实体。
WriteChars方法:以每次一个缓冲区的方式写入文本。
WriteComment方法:写出包含指定文本的注释 <!--...-->。、
WriteDocType方法:写出具有指定名称和可选属性的 DOCTYPE 声明。
下段代码演示了WriteChars方法的用法,其他方法用法类似。
//Handling surrogate pair across buffer streams.
char [] charArray = new char[4];
char lowChar, highChar;
Random random = new Random();
lowChar = Convert.ToChar(random.Next(0xDC01, 0xDFFF));
highChar = Convert.ToChar(random.Next(0xD801, 0xDBFF));
XmlTextWriter tw = new XmlTextWriter("test.xml", null);
tw.WriteStartElement("Root");
charArray[0] = 'a';
charArray[1] = 'b';
charArray[2] = 'c';
charArray[3] = highChar;
try
{
tw. WriteChars(charArray, 0, charArray.Length);
}
catch (Exception ex) {
}
Array[0] = highChar;
Array[1] = lowChar;
charArray[2] = 'd';
tw.WriteChars(charArray, 0, 3);
tw.WriteEndElement();
2.Flush方法
该方法用于将缓冲区中的所有内容刷新到基础流,并同时刷新基础流。下段代码演示了Flush方法的使用。
XmlTextWriter writer = new XmlTextWriter (Console.Out);
//Use indenting for readability
writer.Formatting = Formatting.Indented;
//Write an XML fragment.
writer.WriteStartElement("book");
writer.WriteElementString("title", "Pride And Prejudice");
writer.WriteEndElement();
writer.Flush();
//Write another XML fragment.
writer.WriteStartElement("cd");
writer.WriteElementString("title", "Americana");
writer.WriteEndElement();
writer.Flush();
//Close the writer.
writer.Close();
3.Close方法
该方法当应用在XML文档的写操作完成后,关闭文档流和基础流。
六、一个完整的XML文件读/写实例
本文最后将使用VS.net开发工具附带的"books.xml"文件来作为示例,为你介绍C#对XML文件的基本操作方法。我们假定books.xml文件的路径为:C:\books.xml。
该文件信息如下:
"books.xml"文件如下:
<xml version='1.0'>
<!-- This file represents a fragment of a book store inventory database -->
<bookstore>
<book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<first-name>Sidas</first-name>
<last-name>Plato</last-name>
</author>
<price>9.99</price>
</book>
</bookstore>1.读取XML文件的方法
XmlReader类是提供XML分析的API,XmlTextReader是旨在处理字节流的实现。 通常情况下,如果你需要将XML作为原始数据进行访问,则可以使用XmlTextReader,这样可不必避免DOM开销。省去对DOM的访问可使读取XML的速度加快。例如,XML文档可能有一个标头节,用于传递该文档以便在其他地方进行处理。XmlTextReader有不同的构造函数,以指定XML数据的位置。
XmlTextReader reader = new XmlTextReader ("books.xml");
加载后,XmlTextReader 通过使用 Read 方法在 XML 数据中移动,按顺序从文档中检索下一个记录。如果不再有记录,则 Read 方法返回假。
while (reader.Read())
{
// Do some work here on the data
...
}
Do While (reader.Read())
' Do some work here on the data
...
Loop
要处理 XML 数据,每个记录都有一个可从 NodeType 属性确定的节点类型。NodeType 枚举返回节点类型后,该示例将测试此节点类型,以查看该类型是元素类型还是文档类型。如果该节点是两种类型中的一种,则此示例将使用 Name 和 Value 属性处理该节点,以显示有关该节点的详细信息。Name 属性返回节点名(如元素和属性名),而 Value 属性返回当前节点(记录)的节点值(节点文本)。
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an Element
Console.Write("<" + reader.Name);
while (reader.MoveToNextAttribute()) // Read attributes
Console.Write(" " + reader.Name + "='" + reader.Value + "'");
Console.Write(">");
break;
case XmlNodeType.DocumentType: // The node is a DocumentType
Console.WriteLine(NodeType + "<" + reader.Name + ">" + reader.Value);
break;
...
}
}
Do While (reader.Read())
Select Case reader.NodeType
Case XmlNodeType.Element ' The node is an Element
Console.Write("<" + reader.Name)
while (reader.MoveToNextAttribute()) ' Read attributes
Console.Write(" " + reader.Name + "='" + reader.Value + "'")
end while
Console.Write(">")
Case XmlNodeType.DocumentType ' The node is a DocumentType
Console.WriteLine(NodeType & "<" & reader.Name & ">" & reader.Value);
...
End Select
Loop
2.写XML文件的方法
首先,我们要创建一个XmlTextWriter类的实例对象。该类的构造函数XmlTextWriter有三种重载形式,其参数分别为一个字符串、一个流对象和一个TextWriter对象。这里我们运用字符串的参数形式,该字符串就指明了所要创建的XML文件的位置,方法如下:
XmlTextWriter textWriter = New XmlTextWriter("C:\\books.xml", null);
在创建完对象后,我们调用WriterStartDocument方法开始写XML文档,下面的实例就是介绍如何具体运用这些方法来完成XML文档的写工作的。
using System;
using System.Xml;
namespace WriteXML
{
class Class1
{
static void Main( string[] args )
{
// 创建XmlTextWriter类的实例对象
XmlTextWriter textWriter = new XmlTextWriter("C:\\myXmFile.xml", null);
// 开始写过程,调用WriteStartDocument方法
textWriter.WriteStartDocument();
// 写入说明
textWriter.WriteComment("First Comment XmlTextWriter Sample Example");
textWriter.WriteComment("myXmlFile.xml in root dir");
// 写入一个元素
textWriter.WriteStartElement("Name", "");
textWriter.WriteString("Student");
textWriter.WriteEndElement();
// 再写入一个元素
textWriter.WriteStartElement("Address", "");
textWriter.WriteString("Colony");
textWriter.WriteEndElement();
// 写入字符
char [] ch = new char[3];
ch[0] = 'a';
ch[1] = 'r';
ch[2] = 'c';
textWriter.WriteStartElement("Char");
textWriter.WriteChars(ch, 0, ch.Length);
textWriter.WriteEndElement();
// 写文档结束,调用WriteEndDocument方法
textWriter.WriteEndDocument();
// 关闭textWriter
textWriter.Close();
}
}
}
XmlNode是一个抽象类,他表示XML文档的一个节点。XmlNodeList是一个节点的有序列表。这两个类组成了.NET Framework中DOM(Document Object Model)的核心。
基于XmlNode的一些类:
XmlLinkedNode:扩展XmlNode。立即返回当前节点之前或之后的节点。给XmlNode添加NextSibling和PreviousSibling属性。
XmlDocument:扩展XmlNode。表示整个文档,执行DOMLevel1和Level2规范
XmlAttrbute: 扩展XmlNode。XmlElement对象的一个属性对象。
XmlCDataSection:扩展XmlCharacterData。表示文档中CData部分的一个对象。
XmlCharacterData:抽象类,为其他类提供文本处理方法。扩展XmlLinkedNode。
XmlComment:扩展XmlCharacterData,表示一个XML注释对象
XmlDeclaration:扩展XmlLinkedNode,表示声明节点(<?xml version='1.0'...>)
XmlDocumentFragment:扩展XmlNode,表示文档树的一个片段。
XmlDocumentType: 扩展XmlLinkedNode,与文档类型声明相关的数据
XmlElement:扩展XmlLinkedNode,一个Xml元素对象
XmlEntity :扩展XmlNode,一个已分析或未分析的实体节点
XmlEntityReferenceNode:扩展XmlLinkedNode,表示一个实体引用节点。
XmlNotation:扩展XmlNode,包含在DTD或模式中声明的记号。
XmlProcessingInstruction:扩展XmlLinkedNode,包含Xml处理指令。
XmlSignificantWhitespace:扩展XmlCharacterData,表示带有空白的节点。
XmlWhitespace:扩展XmlCharacterData表示元素内容中的空白格
XmlText :扩展XmlCharacterData,元素或属性的文本内容。