C#沉淀-Linq to XML實戰(zhàn)

XML類

Linq to XML可以以兩種方式和XML配合。第一種方式是作為簡化的XML操作API,和二種方式是使用本章前面看到的Linq查詢工具

Linq to XML API由很多表示XML樹組件的類組成,其中有三個類比較重要:XElement/XAttribute/XDocument

從示例出發(fā):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            //XDocument表示一個XML文檔
            //XElement表示一個XML元素
            XDocument employees1 =
                new XDocument(
                    //創(chuàng)建一個Employees根節(jié)點
                    new XElement("Employees",
                        //創(chuàng)建兩個子節(jié)點
                        new XElement("Name", "Bob Smith"),
                        new XElement("Name", "Sally Jones") 
                        )
                    );

            //通過Save方法將XML文檔保存
            employees1.Save("Employees.xml");

            //通過Load方法加載XML文檔
            XDocument employees2 = XDocument.Load("Employees.xml");

            //打印出XML文檔結(jié)構(gòu)
            Console.WriteLine(employees2.ToString());

            Console.ReadKey();
        }
    }
}

輸出:

<Employees>
  <Name>Bob Smith</Name>
  <Name>Sally Jones</Name>
</Employees>

XML樹的嵌套關(guān)系

  • XDocument (文檔)
    • XDeclaration ?
    • XDocumentType ?
    • XProcessingInstruction *
    • XElement ? (根節(jié)點)
      • XElement * (節(jié)點)
      • XComment *
      • XAttribute *
      • XProcessingInstruction *

?表示0個或1個;*表示這個或多個

語法解析:

public XDocument(params object[] content);

參數(shù)表示文檔所包含的內(nèi)容,即要添加到此文檔的內(nèi)容對象的參數(shù)列表,上例添加了一個根節(jié)點

public XElement(XName name, params object[] content);

第一個參數(shù)是對象名

第二個參數(shù)以及之后的參數(shù)包含了XML樹的節(jié)點;第二個參數(shù)是一個Params參數(shù),也就是說可以有任意多個參數(shù)

然后在根點中又添加了兩個節(jié)點

使用XML樹的值

用于獲取XML樹的值的方法有:

  • Nodes-所在類為XDocumet/XElement,返回類型是IEnumerable<object>,它會返回當前節(jié)點的所有子節(jié)點,不管什么什么類型,可以使用OfType來指定返回某個類型的節(jié)點,如IEnmerable<XCmment> comments = xd.Nodes().OfType<XComment>();,返回XComment類型的節(jié)點
  • Elements-所在類為XDocumet/XElement,返回類型是IEnumerable<XElement>,它返回當前節(jié)點的XElement子節(jié)點,或所有具有某個 名字的子節(jié)點
  • Element-所在類為XDocumet/XElement,返回類型是Element,它返回當前一個的Element子節(jié)點,或所有具有某個 名字的子節(jié)點
  • Descendants-所在類為XElement,返回類型是IEnumerable<XElement>,它返回所有的XElement子代節(jié)點,或所有具有某個名字的XElement子代節(jié)點,不管它們處于當前節(jié)點下嵌套的什么層次
  • DescendantsAndSelf-所在類為XElement,返回類型是IEnumerable<XElement>,和Descendants一樣,但是包括當前節(jié)點
  • Ancestors-所在類為XElement,返回類型是IEnumerable<XElement>,返回所有上級XElement節(jié)點,或者所有具有某個名字的上級XElement節(jié)點
  • AncestorsAndSelf-所在類為XElement,返回類型是IEnumerable<XElement>,和AncestorsAndSelf一樣,但是包括當前節(jié)點
  • Parent-所在類為XElement,返回類型是XElement,返回當前節(jié)點的父節(jié)點

示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {

            //XDocument表示一個XML文檔
            //XElement表示一個XML元素
            XDocument employees1 =
                new XDocument(

                //創(chuàng)建一個Employees根節(jié)點
                    new XElement("Employees",

                //創(chuàng)建兩個子節(jié)點
                        new XElement("Employee",
                            new XElement("Name", "Bob Smith"),
                            new XElement("PhoneNumber", "13161861814")),
                        new XElement("Employee",
                            new XElement("Name", "Sally Jones"),
                            new XElement("PhoneNumber", "13161861815"),
                            new XElement("PhoneNumber", "13161861816"))

                            ));

            //獲取第一個名為"Employees"的子XElement
            XElement root = employees1.Element("Employees");//其實就是根節(jié)點
            IEnumerable<XElement> employess = root.Elements();//根節(jié)點下所有的子節(jié)點

            foreach (XElement emp in employess)
            {
                //獲取第一個名為"Name"的子XElement
                XElement empNameNode = emp.Element("Name");
                Console.WriteLine(empNameNode.Value);

                //獲取第一個名為"PhoneNumber"的子XElement
                IEnumerable<XElement> empPhones = emp.Elements("PhoneNumber");
                foreach (XElement phone in empPhones)
                    Console.WriteLine(phone.Value);
            }

            Console.ReadKey();
        }
    }
}

增加節(jié)點以及操作XML

可以使用Add方法為現(xiàn)在元素增加子元素

Add方法允許一次增加任意多個元素,不管增加的節(jié)點類型是什么類型

示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            //創(chuàng)建xml文檔,并添加一個根節(jié)點一個子節(jié)點
            XDocument xd = new XDocument(
                new XElement("root",
                    new XElement("first")
                    )
                );

            Console.WriteLine("Origianl tree");
            Console.WriteLine(xd);//展示一下目前的樹結(jié)構(gòu)
            Console.WriteLine();

            //獲取第一個元素
            XElement rt = xd.Element("root");

            //添加子元素
            rt.Add(new XElement("second"));

            //連續(xù)添加三個元素
            rt.Add(
                new XElement("thrid"),
                new XElement("fourth"),
                new XElement("fifth")
                );
            //Add方法會把新添加的子節(jié)點放到已有的子節(jié)點之后

            Console.WriteLine("Modified tree");
            Console.WriteLine(xd);

            Console.ReadKey();
        }
    }
}

其他常用方法

  • AddFirst - 在當前既有的子節(jié)點之前添加新的子節(jié)點
  • AddBeforeSelf - 在同級別的當前節(jié)點之前增加新的子節(jié)點
  • AddAfterSelf - 在同級別的當前節(jié)點之后增加新的子節(jié)點
  • Remove - 刪除當前所選的節(jié)點及內(nèi)容
  • RemoveNodes - 刪除當前所先的的XElements及其內(nèi)容
  • SetElement - 設(shè)置節(jié)點的內(nèi)容
  • ReplaceContent - 替換節(jié)點的內(nèi)容

使用XML特性(屬性)

示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = new XDocument(
                
                new XElement("root",
                    new XAttribute("color","red"),
                    new XAttribute("size","large"),
                    new XElement("first"),
                    new XElement("second")
                    )
                );

            Console.WriteLine(xd);

            Console.ReadKey();
        }
    }
}

輸出:

<root color="red" size="large">
  <first />
  <second />
</root>

XAttributeXElement的構(gòu)造中設(shè)置其屬性值,第一個參數(shù)指定屬性名,第二個參數(shù)指定屬性值

再來看看獲取特性值的示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = new XDocument(
                
                new XElement("root",
                    new XAttribute("color","red"),
                    new XAttribute("size","large"),
                    new XElement("first"),
                    new XElement("second")
                    )
                );

            Console.WriteLine(xd);
            Console.WriteLine("---------");

            XElement rt = xd.Element("root");

            XAttribute color = rt.Attribute("color");
            XAttribute size = rt.Attribute("size");

            Console.WriteLine("顏色值:{0}",color.Value);
            Console.WriteLine("大小值:{0}", size.Value);

            Console.ReadKey();
        }
    }
}

輸出:

<root color="red" size="large">
  <first />
  <second />
</root>
---------
顏色值:red
大小值:large

移除特性

示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = new XDocument(
                
                new XElement("root",
                    new XAttribute("color","red"),
                    new XAttribute("size","large"),
                    new XElement("first"),
                    new XElement("second")
                    )
                );

            Console.WriteLine(xd);
            Console.WriteLine("---------");

            XElement rt = xd.Element("root");

            //第一種移除方法
            rt.Attribute("color").Remove();
            //第二種移除方法
            rt.SetAttributeValue("size", null);

            Console.WriteLine(xd);

            Console.ReadKey();
        }
    }
}

輸出

<root color="red" size="large">
  <first />
  <second />
</root>
---------
<root>
  <first />
  <second />
</root>

增加與修改特性值

示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = new XDocument(
                
                new XElement("root",
                    new XAttribute("color","red"),
                    new XAttribute("size","large"),
                    new XElement("first"),
                    new XElement("second")
                    )
                );

            Console.WriteLine(xd);
            Console.WriteLine("---------");

            XElement rt = xd.Element("root");

            //修改特性值
            rt.SetAttributeValue("color","green");
            //添加一個新的特性
            rt.SetAttributeValue("width", "narrow");

            Console.WriteLine(xd);

            Console.ReadKey();
        }
    }
}

輸出:

<root color="red" size="large">
  <first />
  <second />
</root>
---------
<root color="green" size="large" width="narrow">
  <first />
  <second />
</root>

關(guān)于節(jié)點的其他類型

  • XComment - XML文檔的注釋;語法new XComment("這是一行注釋")
  • XDeclaration - XML的版本號、字符編碼類型等元數(shù)據(jù),這叫XML聲明 ;語法new XDeclaration("1.0","utf08","yes"),對應(yīng)結(jié)果為<?xml version="1.0" encoding="uft-8" standlaone="yes"?>
  • XProcessingInstruction- XML的處理指令;語法new XProcessingInstruction ("xml-stylesheet",@"href=""stories"" type=""text/css"""),對應(yīng)結(jié)果為:<?xml-stylesheet href="stories.css" type="text/css">

完整示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = new XDocument(
                new XDeclaration("1.0","utf08","yes"),
                new XComment("這是一行注釋"),
                new XProcessingInstruction ("xml-stylesheet",@"href=""stories"" type=""text/css"""),

                new XElement("root",
                    new XAttribute("color","red"),
                    new XAttribute("size","large"),
                    new XElement("first"),
                    new XElement("second")
                    )
                );

            Console.WriteLine(xd);

            Console.ReadKey();
        }
    }
}

輸出:

<!--這是一行注釋-->
<?xml-stylesheet href="stories" type="text/css"?>
<root color="red" size="large">
  <first />
  <second />
</root>

使用Linq to XML的Linq查詢

示例一:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = new XDocument(
                new XDeclaration("1.0", "utf08", "yes"),
                new XComment("這是一行注釋"),
                new XProcessingInstruction("xml-stylesheet", @"href=""stories"" type=""text/css"""),

                new XElement("root",

                    new XAttribute("color", "red"),
                    new XAttribute("size", "large"),

                    new XElement("first",
                        new XAttribute("color", "red"),
                        new XAttribute("size", "large")
                    ),
                    new XElement("second",
                        new XAttribute("color", "green"),
                        new XAttribute("size", "large")
                    ),
                    new XElement("thrid",
                        new XAttribute("color", "yello"),
                        new XAttribute("size", "large")
                    )
                    )
                );

            xd.Save("Hello.xml");
            Console.WriteLine(xd);

            XDocument doc = XDocument.Load("Hello.xml");
            XElement root = doc.Element("root");

            var xyz = from e in root.Elements()
                      where e.Name.ToString().Length == 5 // 獲取五個字符的元素
                      select e;

            foreach (var item in xyz)
            {
                Console.WriteLine(item.Name.ToString());
            }

            Console.WriteLine("-------");

            foreach (var item in xyz)
            {
                Console.WriteLine("Name:{0}, Color:{1}, Size:{2}",item.Name,item.Attribute("color").Value,item.Attribute("size").Value);
            }
            Console.ReadKey();
        }
    }
}

輸出:

<!--這是一行注釋-->
<?xml-stylesheet href="stories" type="text/css"?>
<root color="red" size="large">
  <first color="red" size="large" />
  <second color="green" size="large" />
  <thrid color="yello" size="large" />
</root>
first
thrid
-------
Name:first, Color:red, Size:large
Name:thrid, Color:yello, Size:large

示例二:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml.Linq;

namespace CodeForLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = new XDocument(
                new XDeclaration("1.0", "utf08", "yes"),
                new XComment("這是一行注釋"),
                new XProcessingInstruction("xml-stylesheet", @"href=""stories"" type=""text/css"""),

                new XElement("root",

                    new XAttribute("color", "red"),
                    new XAttribute("size", "large"),

                    new XElement("first",
                        new XAttribute("color", "red"),
                        new XAttribute("size", "large")
                    ),
                    new XElement("second",
                        new XAttribute("color", "green"),
                        new XAttribute("size", "large")
                    ),
                    new XElement("thrid",
                        new XAttribute("color", "yello"),
                        new XAttribute("size", "large")
                    )
                    )
                );

            xd.Save("Hello.xml");
            Console.WriteLine(xd);

            Console.WriteLine("\n-------");

            XDocument doc = XDocument.Load("Hello.xml");
            XElement root = doc.Element("root");

            var xyz = from e in root.Elements()
                      select new {e.Name, color=e.Attribute("color").Value };

            foreach (var item in xyz)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("\n-------");

            foreach (var item in xyz)
            {
                Console.WriteLine("{0,-6}, color:{1,-7}",item.Name,item.color);
            }
            Console.ReadKey();
        }
    }
}

輸出:

<!--這是一行注釋-->
<?xml-stylesheet href="stories" type="text/css"?>
<root color="red" size="large">
  <first color="red" size="large" />
  <second color="green" size="large" />
  <thrid color="yello" size="large" />
</root>

-------
{ Name = first, color = red }
{ Name = second, color = green }
{ Name = thrid, color = yello }

-------
first , color:red
second, color:green
thrid , color:yello
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容