XML文档的读取可以通过XmlReader类来实现。XmlReader类是一个提供对XML数据的非缓存、只进只读访问的抽象基类。该类符合W3C可扩展标记语言(XML)1.0和XML中的命名空间的建议。
XmlReader类支持从流或文件读取XML数据。该类定义的方法和属性支持浏览数据并读取节点的内容,其中当前节点指读取器所处的节点。使用任何返回当前节点值的读取方法和属性推进读取器。XmlReader功能如下所述。
· 检查字符是不是合法的XML字符,元素和属性的名称是不是有效的XML名称。
· 检查XML文档的格式是否正确。
· 根据DTD或架构验证数据。
· 从XML流检索数据或使用提取模型跳过不需要的记录。
XmlReader类用于读取XML文档,如同普通文件的读取类StreamReader一样。下面介绍一个实例演示XML文档的读取。介绍实例之前,先给出一个简单的XML文档,作为程序演示之用:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--This is a letter-->
<mail date='01-01-07'>
<date>
<month>01</month >
<day>01</day>
<year>07</year>
</date>
<to>Wang</to>
<from>Zhao</from>
<title>Thanks</title>
<body>Thank You!</body>
</mail>
将其存为C:\test.xml。
创建一个Windows控制台应用程序,演示XmlReader的使用。
(1)创建一个名为XmlRead的控制台应用程序项目。
(2)修改Program.cs文件的内容如下:
namespace XmlRead
{
class Program
{
static void Main(string[] args)
{
//XML文件路径
string path = @"c:\test.xml";
//尝试读取该XML文件
try
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.IgnoreWhitespace = true;
settings.IgnoreComments = true;
XmlReader reader = XmlReader.Create(path, settings);
Console.WriteLine("XmlReader创建成功!");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
图11-1 运行结果
|
}
}
}
按Ctrl+F5组合键运行程序,运行结果如图11-1所示。
代码中定义了一个XmlReader的变量,并根据XML文件的路径创建了该实例。下面简要地介绍代码中给出的参数。
· 要求数据是格式正确的XML文档:ConformanceLevel = ConformanceLevel.Document。
· 要求数据是格式正确的XML已分析实体:ConformanceLevel = ConformanceLevel. Fragment。
· 需要数据针对DTD进行验证:ProhibitDtd = false ValidationType = ValidationType.DTD。
· 需要数据针对XML架构进行验证:ValidationType = ValidationType.Schema,Schemas = 要用于验证的XmlSchemaSet。
· 需要数据针对内联XML架构进行验证:ValidationType = ValidationType.Schema,ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema。
· 需要类型支持:ValidationType = ValidationType.Schema,Schemas为要使用的Xml- SchemaSet。
若向test.xml文件中加入一些错误的标记,如做如下的修改:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--This is a letter-->
<mail date='01-01-07'>
<date>
<month>01</month >
<day>01</day>
<year>07</year>
</date>
<to>Wang</to>
<from>Zhao</from>
<title>Thanks</title>
<body>Thank You!</body>
下面使用不带参数的方法访问该格式错误的XML文档。
创建一个Windows控制台应用程序,演示XmlReader的使用。
(1)创建一个名为ErrXmlRead的控制台应用程序项目。
(2)修改Program.cs文件的内容如下:
namespace ErrXmlRead
{
class Program
{
static void Main(string[] args)
{
//XML文件路径
string path = @"c:\test.xml";
//尝试读取该XML文件
try
{
XmlReader myReader = XmlReader.Create(path);
//读取XML文件的内容
while (myReader.Read()) ;
Console.WriteLine("读取成功!");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
按Ctrl+F5组合键运行程序,运行结果如图11-2所示。
图11-2 运行结果
代码中定义了一个XmlReader的变量,并根据XML文件的路径创建了该实例。该方式没有使用任何参数,创建XmlReader实例时,C#能自动检测出XML文档的错误,并给出提示。
XmlReader中提供了若干种方法用于XML文档内容的读取。下面首先介绍ReadStart-
Element和ReadEndElement方法配合使用。
创建一个Windows控制台应用程序,演示ReadStartElement和ReadEndElement方法的使用。
(1)创建一个名为ReadStart的控制台应用程序项目。
(2)修改Program.cs文件的内容如下:
namespace ReadStart
{
class Program
{
static void Main(string[] args)
{
//XML文件路径
string path = @"c:\test.xml";
//尝试读取该XML文件
try
{
//初始化myReader的实例
XmlReader myReader = XmlReader.Create(path);
//读取mail节点
myReader.ReadStartElement("mail");
//读取date节点
myReader.ReadStartElement("date");
//读取month节点,输出并结束当前节点
myReader.ReadStartElement("month");
Console.WriteLine("month中包含的内容是:");
Console.WriteLine(myReader.ReadString());
myReader.ReadEndElement();
//读取month节点,输出并结束当前节点
myReader.ReadStartElement("day");
Console.WriteLine("day中包含的内容是:");
Console.WriteLine(myReader.ReadString());
myReader.ReadEndElement();
//读取year节点,输出并结束当前节点
myReader.ReadStartElement("year");
Console.WriteLine("year中包含的内容是:");
Console.WriteLine(myReader.ReadString());
myReader.ReadEndElement();
//结束date节点
myReader.ReadEndElement();
//读取to节点,输出并结束当前节点
myReader.ReadStartElement("to");
Console.WriteLine("to中包含的内容是:");
Console.WriteLine(myReader.ReadString());
myReader.ReadEndElement();
//读取from节点,输出并结束当前节点
myReader.ReadStartElement("from");
Console.WriteLine("from中包含的内容是:");
Console.WriteLine(myReader.ReadString());
myReader.ReadEndElement();
//读取title节点,输出并结束当前节点
myReader.ReadStartElement("title");
Console.WriteLine("title中包含的内容是:");
Console.WriteLine(myReader.ReadString());
myReader.ReadEndElement();
//读取body节点,输出并结束当前节点
myReader.ReadStartElement("body");
Console.WriteLine("body中包含的内容是:");
Console.WriteLine(myReader.ReadString());
myReader.ReadEndElement();
//结束mail节点
myReader.ReadEndElement();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
按Ctrl+F5组合键运行程序,运行结果如图11-3所示。
图11-3 运行结果
可以看到虽然正确地获得了XML文件中各个元素的值,但是却非常烦琐,并且此种方式访问XML文档必须了解XML文档的结构。
下面再介绍一种循环的访问方式,可以迅速地访问XML文档中的内容。
创建一个Windows控制台应用程序,演示访问XML文档内容的方法。
(1)创建一个名为AllRead的控制台应用程序项目。
(2)修改Program.cs文件的内容如下:
namespace AllRead
{
class Program
{
static void Main(string[] args)
{
//XML文件路径
string path = @"c:\test.xml";
//尝试读取该XML文件
try
{
//初始化myReader的实例
XmlReader myReader = XmlReader.Create(path);
//当myReader.Read为真的时候读取XML文件中的内容。
while (myReader.Read())
{
if (myReader.IsStartElement())
{
if (myReader.IsEmptyElement)
Console.WriteLine("<{0}/>", myReader.Name);
else
{
Console.Write("<{0}> ", myReader.Name);
myReader.Read();
if (myReader.IsStartElement())
Console.Write("\r\n<{0}>", myReader.Name);
Console.Write(myReader.ReadString());
Console.WriteLine("</{0}>", myReader.Name);
}
}
}
Console.WriteLine("</mail>");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
图11-4 运行结果
|
按Ctrl+F5组合键运行程序,运行结果如图11-4所示。
程序采用循环的方式依次读取XML文档的内容,可以看到,访问方式比较便捷。
XmlReader不仅可以访问XML文档中的元素,也可以访问XML文档中元素的属性。本小节介绍访问XML文档中元素属性的方法。
创建一个Windows控制台应用程序,演示访问XML文档属性的方法。
(1)创建一个名为PropRead的控制台应用程序项目。
(2)修改Program.cs文件的内容如下:
namespace PropRead
{
class Program
{
static void Main(string[] args)
{
//XML文件路径
string path = @"c:\test.xml";
string date = string.Empty;
//尝试读取该XML文件
try
{
//初始化myReader的实例
XmlReader myReader = XmlReader.Create(path);
//直接跳至mail元素
myReader.IsStartElement("mail");
//获取当前元素即mail元素的date属性
date = myReader.GetAttribute("date");
Console.WriteLine("date为:");
Console.WriteLine(date);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
按Ctrl+F5组合键运行程序,运行结果如图11-5所示。
图11-5 运行结果
使用这种方法必须给出元素的名称和属性的名称,还可以通过另一种方法在不提供这两项信息的情况下输出XML文件中所有的属性。下面介绍一个实例,读出XML文档中全部的属性。
创建一个Windows控制台应用程序,演示循环访问XML文档中全部属性的方法。
(1)创建一个名为PropAllRead的控制台应用程序项目。
(2)修改Program.cs文件的内容如下:
namespace PropAllRead
{
class Program
{
static void Main(string[] args)
{
//XML文件路径
string path = @"c:\test.xml";
string date = string.Empty;
//尝试读取该XML文件
try
{
//初始化myReader的实例
XmlReader myReader = XmlReader.Create(path);
while (myReader.Read())
{
//检测当前myReader是否含有属性
if (myReader.HasAttributes)
{
Console.WriteLine("<" + myReader.Name + ">的属性:");
while (myReader.MoveToNextAttribute())
{
Console.WriteLine("{0}={1}",myReader.Name,myReader.
Value);
}
// 移至下一个元素
myReader.MoveToElement();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
图11-6 运行结果
|
}
}
}
按Ctrl+F5组合键运行程序,运行结果如图11-6所示。
可以看到,这种方式比较简单地读取了文档中所有的属性。