天天看點

循環遞歸周遊XML文檔或按某要求周遊XML文檔

<a href="http://blog.vsharing.com/wswa915/A914480.html">http://blog.vsharing.com/wswa915/A914480.html</a>

循環遞歸周遊xml文檔的所有節點或按某種要求來周遊xml文檔的節點

下面的執行個體是循環遞歸周遊xml文檔并讀取文本節點的内容

CDList.xml文檔如下:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;

&lt;catalog&gt;

    &lt;cd&gt;

       &lt;title&gt;Empire Burlesque&lt;/title&gt;

       &lt;artist&gt;Bob Dylan&lt;/artist&gt;

       &lt;country&gt;USA&lt;/country&gt;

       &lt;company&gt;Columbia&lt;/company&gt;

       &lt;price&gt;10.90&lt;/price&gt;

       &lt;year&gt;1985&lt;/year&gt;

    &lt;/cd&gt;

       &lt;title&gt;Unchain my heart&lt;/title&gt;

       &lt;artist&gt;Joe Cocker&lt;/artist&gt;

       &lt;company&gt;EMI&lt;/company&gt;

       &lt;price&gt;8.20&lt;/price&gt;

       &lt;year&gt;1987&lt;/year&gt;

&lt;/catalog&gt;

private void button1_Click(object sender, EventArgs e)

{

     this.FindNode();

}

private void FindNode()

     XmlDocument doc = new XmlDocument();

     doc.Load(@"f:\svse\CDList.xml");//加載XML文檔

     foreach (XmlNode node in doc.ChildNodes)

   {

         if (node.HasChildNodes)//判斷是否有子節點

         {

              FindNode(node);                  

         }

      }

private void FindNode(XmlNode node)

    foreach (XmlNode subNode in node.ChildNodes)

    {

        FindNode(subNode); //實作遞歸周遊

//利用if語句隻對文本節點進行相關的處理。

        if (subNode.Name == "#text")//#text為文本節點的名字

        {

           this.textBox1.Text += "\r\n" + subNode.Value;//目前節點的值

        }

     }

注意:目前節點的另外幾個重要屬性和方法的用法

屬性FirstChild,傳回目前節點的第一個子節點

屬性NextSibling,傳回目前節點的第一個兄弟節點

----------------------------------------------------------------------------------------

//下面的示例通過XML資料流來讀取 XML 檔案并顯示每個節點。

items.xml 文檔如下: 

&lt;?xml version="1.0"?&gt;

&lt;!-- This is a sample XML document --&gt;

&lt;!DOCTYPE Items [&lt;!ENTITY number "123"&gt;]&gt;

&lt;Items&gt;

  &lt;Item&gt;Test with an entity: &amp;number;&lt;/Item&gt;

  &lt;Item&gt;Test with a child element &lt;more/&gt; stuff&lt;/Item&gt;

  &lt;Item&gt;Test with a CDATA section &lt;![CDATA[&lt;456&gt;]]&gt; def&lt;/Item&gt;

  &lt;Item&gt;Test with a_ char entity: &amp;#65;&lt;/Item&gt;

  &lt;!-- Fourteen_ chars in this element.--&gt;

  &lt;Item&gt;1234567890ABCD&lt;/Item&gt;

&lt;/Items&gt;

周遊程式片斷如下:

XmlReader reader = XmlReader.Create("item.xml");

//當第一次建立和初始化 XmlReader 時,沒有可用的資訊。必須調用 Read 讀取第一個節點。

reader.MoveToContent();

// Parse the file and display each of the nodes.

while (reader.Read())

  switch (reader.NodeType)

  {

      case XmlNodeType.Element:

          Console.Write("&lt;{0}&gt;", reader.Name);

          break;

      case XmlNodeType.Text:

          Console.Write(reader.Value);

      case XmlNodeType.CDATA:

          Console.Write("&lt;![CDATA[{0}]]&gt;", reader.Value);

      case XmlNodeType.ProcessingInstruction:

          Console.Write("&lt;?{0} {1}?&gt;", reader.Name, reader.Value);

      case XmlNodeType.Comment:

          Console.Write("&lt;!--{0}--&gt;", reader.Value);

      case XmlNodeType.XmlDeclaration:

          Console.Write("&lt;?xml version='1.0'?&gt;");

      case XmlNodeType.Document:

      case XmlNodeType.DocumentType:

          Console.Write("&lt;!DOCTYPE {0} [{1}]", reader.Name, reader.Value);

      case XmlNodeType.EntityReference:

          Console.Write(reader.Name);

      case XmlNodeType.EndElement:

          Console.Write("&lt;/{0}&gt;", reader.Name);

  }

下面是book.xml檔案

&lt;book&gt;

  &lt;title&gt;Pride And Prejudice&lt;/title&gt;

  &lt;price&gt;19.95&lt;/price&gt;

&lt;/book&gt;

//通過XML資料流對XML文檔進行處理。

using System;

using System.xml;

static void Main(String[] args)

  using (XmlReader reader = XmlReader.Create("f:\\svse\\book.xml"))

     reader.Read();

     //檢查目前節點是否為元素并将讀取器推進到下一個節點

     //該方法先後調用IsStartElement和Read将你定位在輸入流中所找到的元素的内容上。

     reader.ReadStartElement("book"); //挖到子節點

     reader.ReadStartElement("title");

     Console.Write("The content of the title element:  ");

     // ReadString() 方法,該方法傳回元素的内容、文本、空白、重要空白或 CDATA 節點。

    // 如果定位在元素上,ReadString 将所有文本、重要的空白、空白和 CDATA 節點串聯在一起,

    // 然後将串聯在一起的資料作為元素内容傳回。當遇到任何标記時,它就會停止。

   Console.WriteLine(reader.ReadString());  

   reader.ReadEndElement();

   reader.ReadStartElement("price");

   Console.Write("The content of the price element:  ");

   Console.WriteLine(reader.ReadString());

   reader.ReadEndElement();      

------------------------------------------------------------------------

讀例程

XML檔案

    &lt;!-- sample xml file --&gt;

    &lt;bookstore&gt;

      &lt;book genre='novel' ISBN='10-861003-324'&gt;

        &lt;title&gt;The Handmaid's Tale&lt;/title&gt;

        &lt;price&gt;19.95&lt;/price&gt;

      &lt;/book&gt;

      &lt;book genre='novel' ISBN='1-861001-57-5'&gt;

        &lt;title&gt;Pride And Prejudice&lt;/title&gt;

        &lt;price&gt;24.95&lt;/price&gt;

&lt;/bookstore&gt;

//取每個書節點上的ISBN屬性

    using (XmlReader reader = XmlReader.Create("books.xml"))

        reader.ReadToFollowing("book");//一直讀取,直到找到具有指定限定名的元素。

        do

        {  

           Console.WriteLine("ISBN: {0}", reader.GetAttribute("ISBN")); //獲得指定屬性的值

         }while (reader.ReadToNextSibling("book"));

         //ReadToNextSibling("book")方法,讓 XmlReader 前進到下一個具有指定限定名的同級元素

根據上面執行個體可以考慮當要讀取xml中的使用者名和密碼時可以這樣設計xml文檔。

&lt;login&gt;

          &lt;user name=’zhang’ pwd=’123’/&gt;

          &lt;user name=’wang’ pwd=’456’/&gt;

&lt;/login&gt;

跳到子節點

    using (XmlReader reader = XmlReader.Create("2books.xml"))

        //讓 XmlReader 前進到下一個具有指定限定名的子代元素。

        reader.ReadToDescendant("book");        // 第一個book

       //跳過目前節點的子級。定位到下一個同級節點上。可能是Whitespace節點

        reader.Skip();                                         

       //檢查目前節點是否是内容節點。

       //如果此節點不是内容節點,則讀取器向前跳至下一個内容節點或檔案結尾。

        reader.MoveToContent();                    // 第二個book

    }

總結:

ReadToFollowing(string)

ReadToNextSibling(string)

ReadToDescendant()

Skip()

以上四個方法都可以定位,它們之間有何差別呢?

ReadToFollowing(string):是從目前位置一直讀取,直到找到具有指定限定名的元素。

ReadToNextSibling(string):讓 XmlReader 前進到下一個具有指定限定名的同級元素

ReadToDescendant(string):讓 XmlReader 前進到下一個具有指定限定名的子代元素

Skip():跳過目前節點的子級。定位到下一個同級節點上。可能是Whitespace節點