在.net里面读取xml文件有两种方法,一种是线形模型,一种是对象模型。
线性模型示例
string fileName=@"D:\Documents and Settings\桌面\xml\TestXmlTestReader\Company.xml";
XmlTextReader tr=new XmlTextReader(fileName);
listBox1.Items.Clear();
while(tr.Read())
{
if (tr.NodeType==XmlNodeType.Text)
{
listBox1.Items.Add(tr.Value);
}
}
tr.Close();
而在MSXML DOM中也有这两种读取方法,其中的线形模型就是(SAX)。如果要使用MSXML DOM必须下载MSXML组件安装,并在工程中引用。
C#中使用XMLReader读取XML文件:Create (String URI, XmlReaderSettings xs)
例子:
XmlReaderSettings settings = new XmlReaderSettings();
string path = "d:\\books.xml";
XmlReader reader = XmlReader.Create(path, settings);
XMLReader对象常用属性:
名称 | 说明 |
当在派生类中被重写时,获取当前节点上的属性数。 | |
当在派生类中被重写时,获取当前节点的基 URI。 | |
获取一个值,该值指示 XmlReader 是否实现 ReadValueChunk 方法。 | |
获取一个值,该值指示此读取器是否可以分析和解析实体。 | |
当在派生类中被重写时,获取 XML 文档中当前节点的深度。 | |
当在派生类中被重写时,获取一个值,该值指示此读取器是否定位在流的结尾。 | |
获取一个值,该值指示当前节点是否有任何属性。 | |
当在派生类中被重写时,获取一个值,该值指示当前节点是否可以具有 Value。 | |
当在派生类中被重写时,获取一个值,该值指示当前节点是否是从 DTD 中定义的默认值生成的属性。 | |
当在派生类中被重写时,获取一个值,该值指示当前节点是否为空元素(例如 <MyElement/>)。 | |
已重载。 当在派生类中被重写时,获取此属性的值。 | |
当在派生类中被重写时,获取当前节点的本地名称。 | |
当在派生类中被重写时,获取当前节点的限定名。 | |
当在派生类中被重写时,获取读取器定位在其上的节点的命名空间 URI(采用 W3C 命名空间规范中定义的形式)。 | |
当在派生类中被重写时,获取与该实现关联的 XmlNameTable。 | |
当在派生类中被重写时,获取当前节点的类型。 | |
当在派生类中被重写时,获取与当前节点关联的命名空间前缀。 | |
当在派生类中被重写时,获取读取器的状态。 | |
获取用于创建此 XmlReader 实例的 XmlReaderSettings 对象。 | |
当在派生类中被重写时,获取当前节点的文本值。 | |
获取当前节点的公共语言运行库 (CLR) 类型。 | |
当在派生类中被重写时,获取当前的 xml:lang 范围。 | |
当在派生类中被重写时,获取当前的 xml:space 范围。 |
常用方法:
名称 | 说明 |
当在派生类中被重写时,将 ReadState 更改为 Closed。 | |
已重载。 创建一个新的 XmlReader 实例。 | |
已重载。 当在派生类中被重写时,获取属性的值。 | |
获取当前实例的 Type。 (继承自 Object。) | |
获取一个值,该值指示字符串参数是否是有效的 XML 名称。 | |
获取一个值,该值指示该字符串参数是否是有效的 XML 名称标记。 | |
已重载。 测试当前内容节点是否是开始标记。 | |
已重载。 当在派生类中被重写时,移动到指定的属性。 | |
检查当前节点是否是内容(非空白文本、CDATA、Element、EndElement、EntityReference 或 EndEntity)节点。如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。它跳过以下类型的节点:ProcessingInstruction、DocumentType、Comment、Whitespace 或 SignificantWhitespace。 | |
当在派生类中被重写时,移动到包含当前属性节点的元素。 | |
当在派生类中被重写时,移动到第一个属性。 | |
当在派生类中被重写时,移动到下一个属性。 | |
当在派生类中被重写时,从流中读取下一个节点。 | |
当在派生类中被重写时,将属性值解析为一个或多个 Text、EntityReference 或 EndEntity 节点。 | |
检查当前内容节点是否为结束标记并将读取器推进到下一个节点。 | |
当在派生类中被重写时,将所有内容(包括标记)当做字符串读取。 | |
当在派生类中被重写时,读取表示该节点和所有它的子级的内容(包括标记)。 | |
已重载。 检查当前节点是否为元素并将读取器推进到下一个节点。 | |
返回新的 XmlReader 实例,此实例可用于读取当前节点及其所有子节点。 | |
已重载。 让 XmlReader 前进到下一个匹配的子代元素。 | |
已重载。 一直读取,直到找到命名元素。 | |
已重载。 让 XmlReader 前进到下一个匹配的同级元素。 | |
读取嵌入在 XML 文档中的大量文本流。 | |
当在派生类中被重写时,解析 EntityReference 节点的实体引用。 | |
跳过当前节点的子级。 |
C#中使用XMLWriter写XML文件:
使用 XmlWriter 方法输出 XML 时,在调用 Close 方法前,不会写入元素和属性
StringBuilder output = new StringBuilder();
XmlWriterSettings ws = new XmlWriterSettings();
XmlWriter writer = XmlWriter.Create(output, ws)
常用属性:
名称 | 说明 |
获取用于创建此 XmlWriter 实例的 XmlWriterSettings 对象。 | |
当在派生类中被重写时,获取编写器的状态。 | |
当在派生类中被重写时,获取当前的 xml:lang 范围。 | |
当在派生类中被重写时,获取表示当前 xml:space 范围的 XmlSpace。 |
常用方法:
名称 | 说明 |
当在派生类中被重写时,关闭此流和基础流。 | |
已重载。 创建一个新的 XmlWriter 实例。 | |
当在派生类中被重写时,将缓冲区中的所有内容刷新到基础流,并同时刷新基础流。 | |
当在派生类中被重写时,返回在当前命名空间范围中为该命名空间 URI 定义的最近的前缀。 | |
当在派生类中被重写时,写出在 XmlReader 中当前位置找到的所有属性。 | |
已重载。 当在派生类中被重写时,写出具有指定值的属性。 | |
当在派生类中被重写时,写出包含指定文本的 <![CDATA[...]]> 块。 | |
当在派生类中被重写时,为指定的 Unicode 字符值强制生成字符实体。 | |
当在派生类中被重写时,以每次一个缓冲区的方式写入文本。 | |
当在派生类中被重写时,写出包含指定文本的注释 <!--...-->。 | |
当在派生类中被重写时,写出具有指定名称和可选属性的 DOCTYPE 声明。 | |
已重载。 当在派生类中被重写时,写出包含字符串值的元素。 | |
当在派生类中被重写时,关闭上一个 WriteStartAttribute 调用。 | |
当在派生类中被重写时,关闭任何打开的元素或属性并将编写器重新设置为 Start 状态。 | |
当在派生类中被重写时,关闭一个元素并弹出相应的命名空间范围。 | |
当在派生类中被重写时,按 &name; 写出实体引用。 | |
当在派生类中被重写时,关闭一个元素并弹出相应的命名空间范围。 | |
当在派生类中被重写时,写出指定的名称,确保它是符合 W3C XML 1.0 建议 (http://www.w3.org/TR/1998/REC-xml-19980210#NT-Name) 的有效名称。 | |
当在派生类中被重写时,写出指定的名称,确保它是符合 W3C XML 1.0 建议 (http://www.w3.org/TR/1998/REC-xml-19980210#NT-Name) 的有效 NmToken。 | |
当在派生类中被重写时,将所有内容从读取器复制到编写器并将读取器移动到下一个同级的开始位置。 | |
当在派生类中被重写时,写出在名称和文本之间带有空格的处理指令,如下所示:<?name text?>。 | |
当在派生类中被重写时,写出命名空间限定的名称。此方法查找位于给定命名空间范围内的前缀。 | |
已重载。 当在派生类中被重写时,手动编写原始标记。 | |
已重载。 当在派生类中被重写时,编写属性的起始内容。 | |
已重载。 当在派生类中被重写时,编写 XML 声明。 | |
已重载。 当在派生类中被重写时,写出指定的开始标记。 | |
当在派生类中被重写时,编写给定的文本内容。 | |
当在派生类中被重写时,为代理项字符对生成并编写代理项字符实体。 | |
已重载。 编写单一的简单类型化值。 | |
当在派生类中被重写时,写出给定的空白。 |
注意:若要执行数据验证,请使用验证 XmlReader。若要从 XmlDocument 中读取 XML 数据,请使用 XmlNodeReader。
C#利用XmlTextReader读取XML节点数据
xml内容:
<?xml version="1.0" encoding="utf-8" ?>
<google>
<googleColorBorder>f6fbff</googleColorBorder>
<googleColorBG>f6fbff</googleColorBG>
<googleColorLink>666666</googleColorLink>
<googleColorText>046b7A</googleColorText>
<googleColorUrl>008000</googleColorUrl>
</google>
cs代码:
protected void Page_Load(object sender, EventArgs e)
{
XmlTextReader xtr = new XmlTextReader("c:\\AdColor2.xml");
while (xtr.Read()) {
if (xtr.NodeType == XmlNodeType.Element && xtr.LocalName == "googleColorBorder") {
Response.Write(xtr.ReadString() + "<br/>");
}
if (xtr.NodeType == XmlNodeType.Element && xtr.LocalName == "googleColorBG")
{
Response.Write(xtr.ReadString() + "<br/>");
}
if (xtr.NodeType == XmlNodeType.Element && xtr.LocalName == "googleColorLink")
{
Response.Write(xtr.ReadString() + "<br/>");
}
if (xtr.NodeType == XmlNodeType.Element && xtr.LocalName == "googleColorText")
{
Response.Write(xtr.ReadString() + "<br/>");
}
if (xtr.NodeType == XmlNodeType.Element && xtr.LocalName == "googleColorUrl")
{
Response.Write(xtr.ReadString() + "<br/>");
}
}
}
0
0
0
(请您对文章做出评价)
C#读取XML文档使用XMLTextReader类浅析
http://developer.51cto.com 2009-08-12 16:46 花开红艳艳 百度空间 我要评论(0)
C#读取XML文档两种方法的比较从何谈起呢?让我们首先来看看XMLTextReader和XmlDocument读取XML文件的比较:
C#读取XML文档之在.NET框架的System.XML名称空间中包含的XMLTextReader类不需要对系统资源要求很高,就能从XML文件中快速读取数据。使用XMLTextReader类能够从XML文件中读取数据,并且将其转换为HTML格式在浏览器中输出。
读本文之前,读者需要了解一些基本知识:XML、HTML、C#编程语言,以及.NET尤其是ASP.NET框架的一些知识。
C#读取XML文档的解决为目的,微软公司的.NET框架为开发者提供了许多开发的便利,随着XML的重要性不断增长,开发者们都期待着有一整套功能强大的XML工具被开发出来。.NET框架没有辜负我们的这番期望,在System.XML 名称空间中组织进了以下几个用于XML的类:
XMLTextReader------提供以快速、单向、无缓冲的方式存取XML数据。(单向意味着你只能从前往后读取XML文件,而不能逆向读取)
XMLValidatingReader------与XMLTextReader类一起使用,提供验证DTD、XDR和XSD架构的能力。
XMLDocument------遵循W3C文档对象模型规范的一级和二级标准,实现XML数据随机的、有缓存的存取。一级水平包含了DOM的最基本的部分,而二级水平增加多种改进,包括增加了对名称空间和级连状图表(CSS)的支持。
XMLTextWriter------生成遵循 W3C XML 1.0 规范的XML文件。
本文主要讲述的C#读取XML文档的方法是第一个类XMLTextReader,这个类设计的目的就是从XML文件中快速的读取数据,而对系统资源(主要包括内存和处理器时间)不做很高的要求。在父级程序的控制下,它通过每次只处理一个节点的方式对XML文件进行逐步操作,实现这种工作过程。在XML文件的每个节点中,父级程序能决定该节点的类型,它的属性和数据(如果有的话),以及其他有关该节点的信息。基于这些信息,父级程序可以选择是处理这个节点还是忽略该节点的信息,以满足各种应用程序请求的需要。这被称为抽取式(pull)处理模型,因为父级程序发出请求并且从XML文件中抽取各个节点,然后根据需要处理它或者是不处理它。
我们可以把XMLTextReader类和XML简单应用程序接口,即SAX相比,后者是在编程人员中非常流行的另一种读取XML数据的技术。XMLTextReader 和SAX有一点很相似,它们都不需要占用很多的系统资源,就能迅速的从XML文件读取数据。但是,与XMLTextReader的抽取式模型迥然不同,SAX使用的是推入式模型:XML处理器通过 "事件"告知主机应用程序哪些节点数据是可以获得,那些不能获得;根据需要,主机程序则作出相应的反应或置之不理。换句话说,数据的传送方向是从SAX处理程序中推入到主机。程序员们势必会在抽取式和推入式处理模型谁更有优势的问题上争论一番,但是大家都不可否认的是,两种模型都能很好的进行工作。.NET 框架不支持SAX,但是你能使用现存的SAX工具, 例如 MSXML分析器,用于你的.NET 程序。
C#读取XML文档之XMLTextReader 类有一些构造程序来适应各种各样的情况,比如从一个已经存在的数据流或统一资源定位网址读取数据。最常见的是,你或许想从一个文件读取XML数据,那么也就有一个相应的构造程序来为此服务。这里有一个例子(我的所有代码例子都使用的是C#语言,如果你喜欢使用VISUAL BASIC语言,它们转换起来很容易)。
XMLTextReader myReader;
myReader = New XMLTextReader("c:\data\sales.XML")
创建一个称为Read()方法的循环,这个方法的返回值总是为真,直到到达文件的底部时,返回值才变为假。换句话说, 循环在文件的开始时启动并且读入所有的节点, 一次读入一个节点, 直到到达文件的结尾:
While (myReader.Read()) {
...
// 在这里处理每个节点.
...
}
每次成功调用Read()之后,XMLTextReader实例化程序包含了目前节点(即刚刚从文件中读取的那个节点)的信息。我们可以从XMLTextReader的成员中获得上述信息,就像表格1中描述的一样;并通过NodeType属性判断出当前节点的类型。在节点类型的基础上,程序的代码可以读取节点数据,检查它是否有属性,到底是忽略它还是根据程序需要进行相应的操作和处理。
当使用NodeType属性时,理解节点怎么联系到XML单元是非常重要的。例如, 看下列 XML元素:
﹤city﹥Chongqing﹤/city﹥
C#读取XML文档之XMLtextReader 把这个元素看作 3 个节点,顺序如下:
1.﹤city﹥标签被读为类型 XMLNodeType.Element 节点,元素的名字"city"可从 XMLTextReader 的Name属性中获得。
2.文本数据"Chongqing"被读为类型为XMLNodeType.Text的节点。数据"Chongqing " 可从XMLTextReader 的Value属性中取得。
3.﹤/city﹥标签被读为类型为XMLNodeType.EndElement 节点。同样,元素的名称"city"可从XMLTextReader的Name属性中获得。
这是 3 种重要的节点类型,其它的类型在.NET的说明文档中有详细说明,请大家参阅相关资料。
如果XMLTextReader遇到一个错误, 例如出现违反XML句法的情况,它抛出一个System.XML.XMLException类型的异常。使用这个类的代码应该总是被保护 ( 在Try……Catch块中),就像你以后在演示程序中看到的一样。
本文只是一篇相当简单的介绍C#读取XML文档之XMLTextReader 类的文章,XMLTextReader类有相当多的成员,在这里不可能一一述及。当读入XML数据时,XMLTextReader能提供相当强的灵活性。即便如此,我仍然进行了大量的论述,以保证读者能编制程序来实现现实世界中经常要求完成的任务,也就是从一个XML文件读取数据然后以HTML的格式输出,从而实现在浏览器中的显示。
这个ASP.NET程序(脚本)在服务器上运行并产生一个HTML页面返回浏览器。这段脚本程序在代码段 1 给出,它用来工作使用的 XML 数据文件在代码段 2给出。你能看到这个 XML 文件包含一份表示联系关系的列表;程序的目标即是将这个列表显示出来,为了更容易我们观察,这些列表已经被格式化了。
运行程序:
1. 将代码段1存为XMLTextReader.ASPx文件,将代码段2存为XMLData.XML文件。
2. 把这两个文件都放在一个已经安装好.NET 框架的网络服务器的虚拟文件夹中。
3. 打开 Internet Explorer 并且浏览这个ASPx文件,例如,在一个局域网服务器上, URL 将是 http://localhost/xmltextreader.ASPx。
C#读取XML文档使用XMLTextReader类代码段:XmlTextReader.aspx
C#读取XML文档使用XMLTextReader类的方法就向你介绍到这里,希望对你理解和学习C#读取XML文档使用XMLTextReader类有所帮助。
C#读取XML节点内容方法实例入手让我们来看看C#读取XML节点的实现:
C#读取XML节点的实例讲解就到这里,希望对你了解学习C#读取XML节点有所帮助。
C#读取XML文档实例浅析
http://developer.51cto.com 2009-08-12 15:26 飞翔的烟 百度空间 我要评论(0)
下面是一个C#读取XML文档的比较通用的方法,可以很方便地读取XML文档格式.XML文档如下:
﹤?xml version="1.0" encoding="utf-8" ?﹥
﹤RolesRoot ID="0" RoleName="应用权限配置"
RoleValue="" RoleUrl="" RoleMark=""﹥
﹤Roles ID="CLGL" RoleName="车辆管理"
RoleValue="" RoleUrl="" RoleMark=""﹥
﹤Role ID="CLGL_CLXX" RoleName="车辆基本信息"
RoleValue="" RoleUrl="车辆管理/车辆基本信息" RoleMark=""﹥
﹤RoleChild ID="" RoleName="编辑" RoleValue=""
RoleUrl="" RoleMark="clbjqx"﹥﹤/RoleChild﹥
﹤RoleChild ID="" RoleName="修改" RoleValue=""
RoleUrl="" RoleMark="clxgqx"﹥﹤/RoleChild﹥
﹤RoleChild ID="" RoleName="删除" RoleValue=""
RoleUrl="" RoleMark="clscqx"﹥﹤/RoleChild﹥
﹤/Role﹥
﹤Role ID="CLGL_SJXX" RoleName="司机基本信息"
RoleValue="" RoleUrl="车辆管理/司机基本信息" RoleMark=""﹥
﹤RoleChild ID="" RoleName="编辑" RoleValue=""
RoleUrl="" RoleMark="sjbjqx"﹥﹤/RoleChild﹥
﹤RoleChild ID="" RoleName="修改" RoleValue=""
RoleUrl="" RoleMark="sjxgqx"﹥﹤/RoleChild﹥
﹤RoleChild ID="" RoleName="删除" RoleValue=""
RoleUrl="" RoleMark="sjscqx"﹥﹤/RoleChild﹥
﹤/Role﹥
﹤/Roles﹥
﹤Roles ID="HYGL" RoleName="" RoleValue=""
RoleUrl="" RoleMark=""﹥
﹤Role ID="" RoleName="" RoleValue=""
RoleUrl="" RoleMark=""﹥﹤/Role﹥
﹤Role ID="" RoleName="" RoleValue=""
RoleUrl="" RoleMark=""﹥﹤/Role﹥
﹤Role ID="" RoleName="" RoleValue=""
RoleUrl="" RoleMark=""﹥﹤/Role﹥
﹤/Roles﹥
﹤/RolesRoot﹥
C#读取XML文档的代码如下所示:
/// ﹤summary﹥
/// 获取XML文档中元素的值
/// ﹤/summary﹥
/// ﹤param name="parentNodePath"﹥父级节点位置,如RolesRoot/Roles﹤/param﹥
/// ﹤param name="childNodeName"﹥子节点名称,如要在Role节点下找相关元素值﹤/param﹥
/// ﹤param name="matchElementName"﹥要进行匹配的元素名称,如通过ID元素值来找匹配﹤/param﹥
/// ﹤param name="id"﹥ID元素值﹤/param﹥
/// ﹤param name="elementName"﹥需要获取的元素名称﹤/param﹥
/// ﹤returns﹥﹤/returns﹥
public static string GetXmlElementValue(string parentNodePath,
string childNodeName,string matchElementName,
string id, string elementName)
{
string outPut = string.Empty;
try
{
string xmlpath = ConfigurationManager.
AppSettings["RolesConfig"];
XmlDocument doc = new XmlDocument();
doc.Load(xmlpath);
XmlNodeList nodes = doc.SelectSingleNode
(parentNodePath).ChildNodes;
foreach (XmlElement node in nodes)
{
if (node.Name == childNodeName)
{
if (node.Attributes[matchElementName].Value == id)
{
outPut = node.Attributes[elementName].Value;
}
}
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
return outPut;
}
上面介绍了一般格式C#读取XML文档的方法,下面介绍读取特殊XML文件属性的方法,该XML文档定义了ID属性,如下:
﹤?xml version="1.0" encoding="utf-8" ?﹥
﹤!DOCTYPE RolesRoot [
﹤!ELEMENT Role ANY﹥
﹤!ELEMENT RoleName ANY﹥
﹤!ELEMENT RoleValue ANY﹥
﹤!ELEMENT RoleUrl ANY﹥
﹤!ELEMENT RoleMark ANY﹥
﹤!ATTLIST Role RoleID ID #REQUIRED﹥
﹤!ATTLIST RolesRoot RoleID IDREF #REQUIRED﹥
]﹥
﹤RolesRoot RoleID="0" RoleName="应用权限配置"
RoleValue="" RoleUrl="" RoleMark=""﹥
﹤Role RoleID="CLGL" RoleName="车辆管理" RoleValue=""
RoleUrl="" RoleMark=""﹥
﹤Role RoleID="CLGL_CLXX" RoleName="车辆基本信息"
RoleValue="" RoleUrl="车辆管理/车辆基本信息" RoleMark=""﹥
﹤Role RoleID="CLGL_CLXX_BJ" RoleName="编辑"
RoleValue="" RoleUrl="" RoleMark="clbjqx"﹥﹤/Role﹥
﹤Role RoleID="CLGL_CLXX_XG" RoleName="修改"
RoleValue="" RoleUrl="" RoleMark="clxgqx"﹥﹤/Role﹥
﹤Role RoleID="CLGL_CLXX_SC" RoleName="删除"
RoleValue="" RoleUrl="" RoleMark="clscqx"﹥﹤/Role﹥
﹤/Role﹥
﹤Role RoleID="CLGL_SJXX" RoleName="司机基本信息"
RoleValue="" RoleUrl="车辆管理/司机基本信息" RoleMark=""﹥
﹤Role RoleID="" RoleName="编辑" RoleValue=""
RoleUrl="" RoleMark="sjbjqx"﹥﹤/Role﹥
﹤Role RoleID="" RoleName="修改" RoleValue=""
RoleUrl="" RoleMark="sjxgqx"﹥﹤/Role﹥
﹤Role RoleID="" RoleName="删除" RoleValue=""
RoleUrl="" RoleMark="sjscqx"﹥﹤/Role﹥
﹤/Role﹥
﹤/Role﹥
﹤/RolesRoot﹥
我们通过ID属性进行C#读取XML文档,获取元素的值.
/// ﹤summary﹥
/// 通过ID获取元素值
/// ﹤/summary﹥
/// ﹤param name="id"﹥XML文档中定义的唯一ID属性﹤/param﹥
/// ﹤param name="elementName"﹥对应ID元素下要查找的元素名称﹤/param﹥
/// ﹤returns﹥﹤/returns﹥
public static string GetXmlElementValueById(string id, string elementName)
{
string outPut = string.Empty;
try
{
string xmlpath = ConfigurationManager.AppSettings["RolesConfig"];
XmlDocument doc = new XmlDocument();
doc.Load(xmlpath);
XmlElement elem = doc.GetElementById(id);
outPut = elem.Attributes[elementName].Value;
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
return outPut;
}
C#读取XML文档的相关内容就向你介绍到这里,希望对你学习或了解C#读取XML文档有所帮助。
C#中xml读写文件的方法(xmlreader,xmlwriter)
2008-07-22 12:51
using System;//写入 namespace xmlwriter XmlWriter myWriter = XmlWriter.Create(path, mySettings); myWriter.WriteStartElement("people"); XmlWriter myWriter = XmlWriter.Create(path, mySettings);//创建XMLWRITER实例 XmlWriter myWriter = XmlWriter.Create(path,mySettings); myWriter.WriteStartElement("people"); XmlWriter myWriter = XmlWriter.Create(path,mySettings); myWriter.WriteStartElement("people"); XmlReader myReader = XmlReader.Create(oldpath); XmlWriter myWriter = XmlWriter.Create(path); using System;//读取 namespace xml myReader.ReadStartElement("month"); myReader.ReadStartElement("day"); myReader.ReadStartElement("year"); myReader.ReadEndElement(); myReader.ReadStartElement("to"); myReader.ReadStartElement("from"); myReader.ReadStartElement("title"); myReader.ReadStartElement("body"); myReader.ReadEndElement(); class Test |
如前所述,XmlTextReader非常类似于SAX。它们最大的一个区别是SAX是一种推模型(push model),它把数据拉入应用程序中,开发人员必须接受它,而XmlTextReader是一种拉模型,把应用程序请求的数据拉入该应用程序。这样编程就有一种更简单、更直观的模型。另一个优点是拉模型(pull model)可以选择把什么数据传送到应用程序中。如果不需要所有的数据,就不需要处理它们。而在推模型中,所有的XML数据都必须由应用程序处理,无论是否需要这些数据。
下面介绍一个非常简单的示例,读取XML数据,再详细介绍XmlTextReader类,这些代码在XmlReaderSample1文件夹中。现在用下面的代码替换前面示例中的命名空间MSXML2:
using System.Xml;
还需要从模块级代码中删除下述代码行:
private DOMDocument40 doc;
下面是按钮的单击事件处理程序:
protected void button1_Click (object sender, System.EventArgs e)
{
//Modify this path to find books.xml
string fileName = "..\\..\\..\\books.xml";
//Create the new TextReader Object
XmlTextReader tr = new XmlTextReader(fileName);
//Read in a node at a time
while(tr.Read())
{
if(tr.NodeType == XmlNodeType.Text)
listBox1.Items.Add(tr.Value);
}
}
这是XmlTextReader最简单的用法。首先,用XML文件名创建一个字符串对象,再创建一个新的XmlTextReader,其参数为fileName字符串。 XmlTextReader目前有13种不同的构造函数重载版本,其参数是字符串(文件名和URL)、流和NameTables的不同组合(当元素或属性名出现几次后,它们就可以存储到NameTable中,这样比较操作的速度会较快)。
在初始化一个XmlTextReader对象后,没有选择任何节点。只有在此时,才没有当前节点。在开始tr.Read()循环后,第一个Read()会进入文档中的第一个节点,这个节点一般是XML 声明节点。在本示例,当进入每个节点时,可比较tr.NodeType 和XmlNodeType枚举,找到一个文本节点后,把该文本值添加到列表框,图23-3是加载该列表框后的屏幕图。
图 23-3
1. Read方法
遍历文档有几种方式,如前面的示例所示,Read()可以进入下一个节点。然后查看该节点是否有一个值(HasValue())、该节点是否有属性(HasAttributes())。也可以使用ReadStartElement()方法,查看当前节点是否是起始元素,如果是起始元素,就可以定位到下一个节点上。如果不是起始元素,就引发一个XmlException。调用这个方法与调用Read ()后再调用IsStartElement是一样的。
ReadString() 和 ReadChars()方法都可以从元素中读取文本数据。ReadString()返回一个包含数据的字符串对象,而ReadChars()把数据读入字符数组。
ReadElementString() 类似于ReadString(),但可以把元素名作为参数。如果下一个Content节点不是起始标记,或者Name属性不匹配当前的节点Name,就会引发异常。
下面的示例说明了如何使用ReadElementString()(这段代码在XmlReaderSample2文件夹中)。注意这个示例使用FileStream,所以需要通过using语句来包括System.IO命名空间:
protected void button1_Click (object sender, System.EventArgs e)
{
//use a filestream to get the data
FileStream fs = new FileStream("..\\..\\..\\books.xml", FileMode.Open);
XmlTextReader tr = new XmlTextReader(fs);
while(!tr.EOF)
{
//if we hit an element type, try and load it in the listbox
if(tr.MoveToContent() == XmlNodeType.Element && tr.FTEL=="title")
{
listBox1.Items.Add(tr.ReadElementString());
}
else
{
//otherwise move on
tr.Read();
}
}
}
在while循环中,使用MoveToContent查找类型为XmlNodeType.Element和名称为title的节点。我们使用XmlTextReader的EOF属性作为循环条件。如果节点的类型不是Element,或者名称不是title,else子句就会调用Read() 方法进入下一个节点。查找到一个满足条件的节点后,就把ReadElementString()的结果添加到列表框中。这样就在listbox中添加一个书名。注意,在成功执行了ReadElementString()后,不需要调用Read()方法,这是因为ReadElementString()已经查看了整个Element,然后定位到下一个节点上。
如果删除了if子句中的&& tr.FTEL=="title",在抛出XmlException异常时,就必须捕获它。如果查看一下数据文件,就会发现MoveToContent ()查找到的第一个元素是<bookstore>,因为它是一个元素,所以把检查过程放在if语句中。但是,它不包含简单的文本类型,因此会让ReadElementString()引发一个XmlException异常。解决这个问题的一种方式是把ReadElementString()调用放在它自己的函数中。现在,如果在这个函数中ReadElementString()调用失败,就可以处理错误,返回给调用函数。
下面就调用这个新方法LoadList(),把XmltextReader作为参数。进行了这些修改后,该示例如下所示(这段代码在XmlReaderSample3文件夹中):
protected void button1_Click (object sender, System.EventArgs e)
{
//use a filestream to get the data
FileStream fs = new FileStream("..\\..\\..\\books.xml", FileMode.Open);
XmlTextReader tr = new XmlTextReader(fs);
while(!tr.EOF)
{
//if we hit an element type, try and load it in the listbox
if(tr.MoveToContent() == XmlNodeType.Element)
{
LoadList(tr);
}
else
{
//otherwise move on
tr.Read();
}
}
}
private void LoadList(XmlReader reader)
{
try
{
listBox1.Items.Add(reader.ReadElementString());
}
// if an XmlException is raised, ignore it.
catch(XmlException er){}
}
运行这段代码,结果应与前面示例的结果是一样的。因此,完成这个任务有多种不同的方式。这体现了System.Xml命名空间中类的灵活性。
2. 检索属性数据
在运行示例代码时,注意在读取节点时,没有看到属性。这是因为属性不是文档结构的一部分。针对元素节点,可以检查属性是否存在,并可检索属性值。
例如,如果有属性,HasAttributes就返回true,否则就返回false。AttributeCount属性确定属性的个数。 GetAttribute方法按照名称或索引来获取属性。如果要一次迭代一个属性,就可以使用MoveToFirstAttribute() 和MoveToNextAttribute()方法。
下面的示例迭代XmlReaderSample4中的属性:
protected void button1_Click (object sender, System.EventArgs e)
{
//set this path to match your data path structure
string fileName = "..\\..\\..\\books.xml";
//Create the new TextReader Object
XmlTextReader tr = new XmlTextReader(fileName);
//Read in node at a time