C# XML技術總結之XDocument 和XmlDocument

引言

雖然如今Json在咱們的數據交換中愈來愈成熟,但XML格式的數據還有很重要的地位。html

C#中對XML的處理也不斷優化,那麼咱們如何選擇XML的這幾款處理類 XmlReader,XDocument 和XmlDocument了?node

本文就從對照的方式來總結C#中XML的用法。程序員

簡介

System.Xml 命名空間(XmlDocument)爲處理 XML 提供基於標準的支持。bash

LINQ to XML(XDocument )能夠進行如下操做:dom

  • 從文件或流加載 XML。post

  • 將 XML 序列化爲文件或流。性能

  • 使用功能構造從頭建立 XML 樹。優化

  • 使用 LINQ 查詢來查詢 XML 樹。this

  • 操做內存中的 XML 樹。google

  • 使用 XSD 驗證 XML 樹。

  • 組合使用這些功能將 XML 樹從一種形狀轉換爲另外一種形狀。

 

 

XmlReader,XDocument 和XmlDocument

XDocument 和XmlDocument會把全部的XML全部的節點加載到內存中,而XmlReader則不會把全部節點一塊兒加載到內存,而在必定的內存下處理較大的XML。

若是XML文件結構固定,處理比較簡單,建議使用XmlReader能夠提升程序的性能。

若是XML文件不大或者要作複雜的處理建議使用XDocument。Linq 讓程序員省去了不少繁瑣冗餘的代碼,而且兼容設備也比較多,不像XmlDocument在一些設備和系統中不支持。

 

XDocument VS. XmlDocument

 

比較項 XmlDocument(經典DOM API) XDocument (LINQ to XML API)
  須要熟悉DOM知識  
支持的.NetFramework版本 .NET version 1.0 + .NET version 3.5 or later(Linq引入後)
雜項   Unity3D projects for Windows 8.
Xbox 360 and Windows Phone OS 7.0,必須使用XDocument
Namespace  System.Xml System.Xml.Linq
LINQ to XML 不支持 支持
行號信息 不能提供行號信息 經過IXmlLineInfo提供了行號信息
命名空間 支持寫 支持元素級寫
XPath 不支持 支持, 參考System.Xml.XPath
註釋 不支持 支持可擴展的批註集,請參見 LINQ to XML 批註
校驗Schema 支持,參考Validate(ValidationEventHandler) 支持 ,參考Validate(XmlSchemaSet, ValidationEventHandler)
加載XML 成員方法加載(須要先new XmlDocument())
靜態方法XElement.Load(@"books.xml")

imageimage

 

建立XML文檔

使用XmlDocument 的示例

XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
XmlElement phone1 = doc.CreateElement("Phone");
phone1.SetAttribute("Type", "Home");
phone1.InnerText = "206-555-0144";        
XmlElement phone2 = doc.CreateElement("Phone");
phone2.SetAttribute("Type", "Work");
phone2.InnerText = "425-555-0145";        
XmlElement street1 = doc.CreateElement("Street1");        
street1.InnerText = "123 Main St";
XmlElement city = doc.CreateElement("City");
city.InnerText = "Mercer Island";
XmlElement state = doc.CreateElement("State");
state.InnerText = "WA";
XmlElement postal = doc.CreateElement("Postal");
postal.InnerText = "68042";
XmlElement address = doc.CreateElement("Address");
address.AppendChild(street1);
address.AppendChild(city);
address.AppendChild(state);
address.AppendChild(postal);
XmlElement contact = doc.CreateElement("Contact");
contact.AppendChild(name);
contact.AppendChild(phone1);
contact.AppendChild(phone2);
contact.AppendChild(address);
XmlElement contacts = doc.CreateElement("Contacts");
contacts.AppendChild(contact);
doc.AppendChild(contacts);

使用XDocument 的示例

XElement contacts =
    new XElement("Contacts",
        new XElement("Contact",
            new XElement("Name", "Patrick Hines"),
            new XElement("Phone", "206-555-0144", 
                new XAttribute("Type", "Home")),
            new XElement("phone", "425-555-0145",
                new XAttribute("Type", "Work")),
            new XElement("Address",
                new XElement("Street1", "123 Main St"),
                new XElement("City", "Mercer Island"),
                new XElement("State", "WA"),
                new XElement("Postal", "68042")
            )
        )
    );

 

加載XML文件

使用XmlDocument 的示例

XmlDocument booksFromFile = new XmlDocument();
booksFromFile.Load(@"books.xml");

使用XDocument 的示例

XElement booksFromFile = XElement.Load(@"books.xml");

 

命名空間的處理

使用XmlDocument 的示例

public void addXmlns()
{
    string xml = @"<?xml version=""1.0""?>
                    <kml>
                    <Document>
                    <Placemark>
                    </Placemark>
                    </Document>
                    </kml>";

    var xmldoc = new XmlDocument();

    xmldoc.LoadXml(xml);

    xmldoc.DocumentElement.SetAttribute("xmlns", "http://www.opengis.net/kml/2.2");
    xmldoc.DocumentElement.SetAttribute("xmlns:gx", "http://www.google.com/kml/ext/2.2");
    xmldoc.DocumentElement.SetAttribute("xmlns:kml", "http://www.opengis.net/kml/2.2");
    xmldoc.DocumentElement.SetAttribute("xmlns:atom", "http://www.w3.org/2005/Atom");
    xmldoc.DocumentElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

    string message;
    message = xmldoc.InnerXml;

    Console.WriteLine(message); // shows the updated xml  
}

使用XDocument 的示例

示例1,增長namespace

XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc
 

示例2,讀取含有namespace的文件

string markup = @"
<aw:Root xmlns:aw='http://www.adventure-works.com'>
    <aw:Child1>child one data</aw:Child1>
    <aw:Child2>child two data</aw:Child2>
</aw:Root>";

XmlReader reader = XmlReader.Create(new StringReader(markup));
XElement root = XElement.Load(reader);
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
namespaceManager.AddNamespace("aw", "http://www.adventure-works.com");
XElement child1 = root.XPathSelectElement("./aw:Child1", namespaceManager);
Console.WriteLine(child1);

 

XDocument 

XDocument  VS. XElement

 

XDocument  XElement
XDocument.Load() 加載整個XML文檔  包括根節點 XElement.Load()不會加載XML的根節點

XElement.Load()示例代碼

File.WriteAllText("Test.xml", @"<Root>
    <Child1>1</Child1>
    <Child2>2</Child2>
    <Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XElement.Load");
Console.WriteLine("----");
XElement doc = XElement.Load("Test.xml");
IEnumerable<XElement> childList =
    from el in doc.Elements()
    select el;
foreach (XElement e in childList)
    Console.WriteLine(e);

 

XDocument.Load() 示例代碼:

File.WriteAllText("Test.xml", @"<Root>
    <Child1>1</Child1>
    <Child2>2</Child2>
    <Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XDocument.Load");
Console.WriteLine("----");
XDocument doc = XDocument.Load("Test.xml");
IEnumerable<XElement> childList =
    from el in doc.Elements()
    select el;
foreach (XElement e in childList)
    Console.WriteLine(e);

 

XPath

XPath的強大之處在於處理元素導航還能夠進行計算

示例:

XML文檔

<xml>
    <foo>
        <baz id="1">10</baz>
        <bar id="2" special="1">baa baa</bar>
        <baz id="3">20</baz>
        <bar id="4" />
        <bar id="5" />
    </foo>
    <foo id="123">Text 1<moo />Text 2
    </foo>
</xml>
 
 

C#處理計算

var node = xele.XPathSelectElement("/xml/foo[@id='123']");
var nodes = xele.XPathSelectElements(
"//moo/ancestor::xml/descendant::baz[@id='1']/following-sibling::bar[not(@special='1')]");
var sum = xele.XPathEvaluate("sum(//foo[not(moo)]/baz)");

 

這裏只是總結知識點,但具體的關於更多XPath的內容能夠移步到XPath 教程

 

XML 批註(註釋)

public class MyAnnotation
{
    private string tag;
    public string Tag { get { return tag; } set { tag = value; } }
    public MyAnnotation(string tag)
    {
        this.tag = tag;
    }
}

class Program
{
    static void Main(string[] args)
    {
        XElement root = new XElement("Root", "content");
        root.AddAnnotation(new MyAnnotation("T1"));
        root.AddAnnotation(new MyAnnotation("T2"));
        root.AddAnnotation("abc");
        root.AddAnnotation("def");

        IEnumerable<object> annotationList;
        annotationList = root.Annotations(typeof(MyAnnotation));
        foreach (object ma in annotationList)
            Console.WriteLine(((MyAnnotation)ma).Tag);
        Console.WriteLine("----");

        IEnumerable<object> stringAnnotationList;
        stringAnnotationList = root.Annotations(typeof(string));
        foreach (object str in stringAnnotationList)
            Console.WriteLine((string)str);
    }
}

 

 

總結

如今再寫XML相關的程序建議直接使用XDocument,XmlDocument只是主要仍是兼容之前的代碼。

另外XPath功能讓XDocument如虎添翼,因此你們能夠多研究下XPath.

至於XSD和XSL本文不作涉及,又須要的朋友參看參考文獻

 

參考

LINQ to XML 與其餘 XML 技術

 

1.經過XmlDocument讀寫Xml文檔

2.使用XmlReader讀Xml使用XmlWriter寫Xml

3.使用Linq to xml存取XML

4.經過XmlScheme定義固定格式xml文檔

5.Xml序列化或者反序列化類

6.經過XPath查找Xml節點

7.經過Xslt轉化Xml格式

8.XDocument or XmlDocument

9.W3CSchool中提供的XML相關課程

Introduction to XML and XSLT in C# .NET

相關文章
相關標籤/搜索