雖然如今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 樹從一種形狀轉換爲另外一種形狀。
XDocument 和XmlDocument會把全部的XML全部的節點加載到內存中,而XmlReader則不會把全部節點一塊兒加載到內存,而在必定的內存下處理較大的XML。
若是XML文件結構固定,處理比較簡單,建議使用XmlReader能夠提升程序的性能。
若是XML文件不大或者要作複雜的處理建議使用XDocument。Linq 讓程序員省去了不少繁瑣冗餘的代碼,而且兼容設備也比較多,不像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") |
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") ) ) );
使用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 | XElement |
XDocument.Load() 加載整個XML文檔 包括根節點 | XElement.Load()不會加載XML的根節點 |
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);
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的強大之處在於處理元素導航還能夠進行計算
示例:
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 教程
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本文不作涉及,又須要的朋友參看參考文獻
2.使用XmlReader讀Xml,使用XmlWriter寫Xml
9.W3CSchool中提供的XML相關課程