您的位置: 网站首页 > 程序开发 > C#程序设计 > 第11章 XML编程 > 【11.2 读取XML文档】

11.2 读取XML文档

 

XML文档的读取可以通过XmlReader类来实现。XmlReader类是一个提供对XML数据的非缓存、只进只读访问的抽象基类。该类符合W3C可扩展标记语言(XML1.0XML中的命名空间的建议。

XmlReader类支持从流或文件读取XML数据。该类定义的方法和属性支持浏览数据并读取节点的内容,其中当前节点指读取器所处的节点。使用任何返回当前节点值的读取方法和属性推进读取器。XmlReader功能如下所述。

·    检查字符是不是合法的XML字符,元素和属性的名称是不是有效的XML名称。

·    检查XML文档的格式是否正确。

·    根据DTD或架构验证数据。

·    XML流检索数据或使用提取模型跳过不需要的记录。

11.2.1  使用XmlReader

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

1.目的说明

创建一个Windows控制台应用程序,演示XmlReader的使用。

2.实现步骤

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  运行结果

 

            }

        }

    }

}

3.运行结果

Ctrl+F5组合键运行程序,运行结果如图11-1所示。

4.代码分析

代码中定义了一个XmlReader的变量,并根据XML文件的路径创建了该实例。下面简要地介绍代码中给出的参数。

·    要求数据是格式正确的XML文档:ConformanceLevel = ConformanceLevel.Document

·    要求数据是格式正确的XML已分析实体:ConformanceLevel = ConformanceLevel. Fragment

·    需要数据针对DTD进行验证:ProhibitDtd = false ValidationType = ValidationType.DTD

·    需要数据针对XML架构进行验证:ValidationType = ValidationType.SchemaSchemas = 要用于验证的XmlSchemaSet

·    需要数据针对内联XML架构进行验证:ValidationType = ValidationType.SchemaValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema

·    需要类型支持:ValidationType = ValidationType.SchemaSchemas为要使用的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>

</mail

下面使用不带参数的方法访问该格式错误的XML文档。

1.目的说明

创建一个Windows控制台应用程序,演示XmlReader的使用。

2.实现步骤

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);

            }

        }

    }

}

3.运行结果

Ctrl+F5组合键运行程序,运行结果如图11-2所示。

11-2  运行结果

4.代码分析

代码中定义了一个XmlReader的变量,并根据XML文件的路径创建了该实例。该方式没有使用任何参数,创建XmlReader实例时,C#能自动检测出XML文档的错误,并给出提示。

11.2.2  读取元素值

XmlReader中提供了若干种方法用于XML文档内容的读取。下面首先介绍ReadStart-

ElementReadEndElement方法配合使用。

1.目的说明

创建一个Windows控制台应用程序,演示ReadStartElementReadEndElement方法的使用。

2.实现步骤

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);

            }

        }

    }

}

3.运行结果

Ctrl+F5组合键运行程序,运行结果如图11-3所示。

11-3  运行结果

4.代码分析

可以看到虽然正确地获得了XML文件中各个元素的值,但是却非常烦琐,并且此种方式访问XML文档必须了解XML文档的结构。

下面再介绍一种循环的访问方式,可以迅速地访问XML文档中的内容。

1.目的说明

创建一个Windows控制台应用程序,演示访问XML文档内容的方法。

2.实现步骤

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  运行结果

 

3.运行结果

Ctrl+F5组合键运行程序,运行结果如图11-4所示。

4.代码分析

程序采用循环的方式依次读取XML文档的内容,可以看到,访问方式比较便捷。

11.2.3  读取元素的属性

XmlReader不仅可以访问XML文档中的元素,也可以访问XML文档中元素的属性。本小节介绍访问XML文档中元素属性的方法。

1.目的说明

创建一个Windows控制台应用程序,演示访问XML文档属性的方法。

2.实现步骤

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);

            }

        }

    }

}

3.运行结果

Ctrl+F5组合键运行程序,运行结果如图11-5所示。

11-5  运行结果

4.代码分析

使用这种方法必须给出元素的名称和属性的名称,还可以通过另一种方法在不提供这两项信息的情况下输出XML文件中所有的属性。下面介绍一个实例,读出XML文档中全部的属性。

1.目的说明

创建一个Windows控制台应用程序,演示循环访问XML文档中全部属性的方法。

2.实现步骤

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  运行结果

 

            }

        }

    }

}

3.运行结果

Ctrl+F5组合键运行程序,运行结果如图11-6所示。

4.代码分析

可以看到,这种方式比较简单地读取了文档中所有的属性。