LINQ to XML 比較DOM (C#)LINQ to XML vs. DOM (C#)

本節描述 LINQ to XMLLINQ to XML 和目前主流的 XML 程式設計 API (也就是 W3C 文件物件模型 (DOM)) 之間的一些主要差異。This section describes some key differences between LINQ to XMLLINQ to XML and the current predominant XML programming API, the W3C Document Object Model (DOM).

建構 XML 樹狀的新方式New Ways to Construct XML Trees

在 W3C DOM 中,您可以從下往上建置 XML 樹狀;也就是說,您可以建立文件、建立項目,然後將項目加入到文件中。In the W3C DOM, you build an XML tree from the bottom up; that is, you create a document, you create elements, and then you add the elements to the document.

例如,以下是使用 Microsoft 的 DOM 實作 XmlDocument 建立 XML 樹狀的典型方式:For example, the following would be a typical way to create an XML tree using the Microsoft implementation of DOM, 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);  

這個編碼樣式在視覺上不會提供太多 XML 樹狀的相關資訊。This style of coding does not visually provide much information about the structure of the XML tree. LINQ to XMLLINQ to XML 支援使用這個方法來建構 XML 樹狀結構,但是也支援採用「功能建構」 的替代方法。supports this approach to constructing an XML tree, but also supports an alternative approach, functional construction. 功能結構使用 XElementXAttribute 建構函式來建置 XML 樹狀結構。Functional construction uses the XElement and XAttribute constructors to build an XML tree.

此處說明您如何使用 LINQ to XMLLINQ to XML 功能建構,來建構相同的 XML 樹狀結構:Here is how you would construct the same XML tree by using LINQ to XMLLINQ to XML functional construction:

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 樹狀結構的程式碼縮排可顯示基礎 XML 的結構。Notice that indenting the code to construct the XML tree shows the structure of the underlying XML.

如需詳細資訊,請參閱建立 XML 樹狀結構 (C#)For more information, see Creating XML Trees (C#).

直接使用 XML 項目Working Directly with XML Elements

當您使用 XML 進行程式設計時,您的主要焦點通常是 XML 項目,也可能是屬性。When you program with XML, your primary focus is usually on XML elements and perhaps on attributes. LINQ to XMLLINQ to XML 中,您可以直接使用 XML 項目和屬性。In LINQ to XMLLINQ to XML, you can work directly with XML elements and attributes. 例如,您可以:For example, you can do the following:

  • 完全不使用文件物件來建立 XML 項目。Create XML elements without using a document object at all. 當您必須使用 XML 樹狀結構的片段時,這可以簡化程式設計的方式。This simplifies programming when you have to work with fragments of XML trees.

  • 從 XML 檔案直接載入 T:System.Xml.Linq.XElement 物件。Load T:System.Xml.Linq.XElement objects directly from an XML file.

  • T:System.Xml.Linq.XElement 物件序列化為檔案或資料流。Serialize T:System.Xml.Linq.XElement objects to a file or a stream.

將這個 XML 項目或屬性與 W3C DOM 相比較,後者中的 XML 文件會當做 XML 樹狀結構的邏輯容器使用。Compare this to the W3C DOM, in which the XML document is used as a logical container for the XML tree. 在 DOM 中,XML 節點 (包括項目和屬性) 必須在 XML 文件的內容中建立。In DOM, XML nodes, including elements and attributes, must be created in the context of an XML document. 此處為要在 DOM 中建立名稱項目之節點的片段:Here is a fragment of the code to create a name element in DOM:

XmlDocument doc = new XmlDocument();  
XmlElement name = doc.CreateElement("Name");  
name.InnerText = "Patrick Hines";  
doc.AppendChild(name);  

如果您要跨多個文件使用同一個項目,您必須匯入跨這些文件的節點。If you want to use an element across multiple documents, you must import the nodes across documents. LINQ to XMLLINQ to XML可避免這層複雜度。avoids this layer of complexity.

使用 LINQ to XML 時,您僅能在想要於文件根層級上加入註解或處理指示時,才能使用 XDocument 類別。When using LINQ to XML, you use the XDocument class only if you want to add a comment or processing instruction at the root level of the document.

簡化的名稱和命名空間處理方式Simplified Handling of Names and Namespaces

名稱、命名空間和命名空間前置詞的處理通常是 XML 程式設計的複雜部分。Handling names, namespaces, and namespace prefixes is generally a complex part of XML programming. LINQ to XMLLINQ to XML 不必處理命名空間前置詞,可簡化名稱和命名空間。simplifies names and namespaces by eliminating the requirement to deal with namespace prefixes. 您也可以控制命名空間前置詞。If you want to control namespace prefixes, you can. 但是,如果您決定不明確控制命名空間前置詞,則在序列化期間,LINQ to XMLLINQ to XML 會指派命名空間前置詞 (如有必要),或使用預設的命名空間進行序列化 (如果非必要的話)。But if you decide to not explicitly control namespace prefixes, LINQ to XMLLINQ to XML will assign namespace prefixes during serialization if they are required, or will serialize using default namespaces if they are not. 如果使用預設的命名空間,在產生的文件中將不會有任何命名空間前置詞。If default namespaces are used, there will be no namespace prefixes in the resulting document. 如需詳細資訊,請參閱命名空間概觀 (LINQ to XML) (C#)For more information, see Namespaces Overview (LINQ to XML) (C#).

另一個 DOM 問題是,DOM 不會讓您變更節點的名稱,Another problem with the DOM is that it does not let you change the name of a node. 而是必須建立新的節點,並將所有子節點複製到該節點中,因此會失去原始的節點識別。Instead, you have to create a new node and copy all the child nodes to it, losing the original node identity. LINQ to XMLLINQ to XML 會讓您在節點上設定 XName 屬性,藉以避免這個問題。avoids this problem by enabling you to set the XName property on a node.

載入 XML 的靜態方法支援Static Method Support for Loading XML

LINQ to XMLLINQ to XML 可讓您使用靜態方法 (而非執行個體方法) 來載入 XML。lets you load XML by using static methods, instead of instance methods. 這會簡化載入和剖析的程序。This simplifies loading and parsing. 如需詳細資訊,請參閱如何:從檔案載入 XML (C#)For more information, see How to: Load XML from a File (C#).

移除 DTD 建構函式的支援Removal of Support for DTD Constructs

LINQ to XMLLINQ to XML 會移除實體和實體參考的支援,進一步簡化 XML 程式設計。further simplifies XML programming by removing support for entities and entity references. 實體的管理很複雜,而且不常使用。The management of entities is complex, and is rarely used. 移除這些支援會增進效能並簡化程式設計介面。Removing their support increases performance and simplifies the programming interface. 填入 LINQ to XMLLINQ to XML 樹狀結構時,系統會展開所有 DTD 實體。When a LINQ to XMLLINQ to XML tree is populated, all DTD entities are expanded.

支援片段Support for Fragments

LINQ to XMLLINQ to XML 不提供 XmlDocumentFragment 類別的對等類別。does not provide an equivalent for the XmlDocumentFragment class. 在許多情況下,XmlDocumentFragment 概念可藉由查詢結果來處理,該查詢的類型為 XNodeIEnumerable<T>XElementIEnumerable<T>In many cases, however, the XmlDocumentFragment concept can be handled by the result of a query that is typed as IEnumerable<T> of XNode, or IEnumerable<T> of XElement.

支援 XPathNavigatorSupport for XPathNavigator

LINQ to XMLLINQ to XML 透過 System.Xml.XPath 命名空間中的擴充方法,提供 XPathNavigator 的支援。provides support for XPathNavigator through extension methods in the System.Xml.XPath namespace. 如需詳細資訊,請參閱 System.Xml.XPath.ExtensionsFor more information, see System.Xml.XPath.Extensions.

支援空白字元與縮排Support for White Space and Indentation

LINQ to XMLLINQ to XML 處理空白字元時,比處理 DOM 更為容易。handles white space more simply than the DOM.

常見的案例為讀取縮排的 XML、建立沒有任何空白字元文字節點 (也就是不保留空白字元) 的記憶體中 XML 樹狀結構、在 XML 上執行某些作業,然後儲存包含縮排的 XML。A common scenario is to read indented XML, create an in-memory XML tree without any white space text nodes (that is, not preserving white space), perform some operations on the XML, and then save the XML with indentation. 當您序列化具有格式的 XML 時,只會保留 XML 樹狀結構中的有效空白字元。When you serialize the XML with formatting, only significant white space in the XML tree is preserved. 這是 LINQ to XMLLINQ to XML 的預設行為。This is the default behavior for LINQ to XMLLINQ to XML.

其他常見案例為讀取與修改已經過刻意縮排的 XML。Another common scenario is to read and modify XML that has already been intentionally indented. 您可能不想用任何方式變更這個縮排。You might not want to change this indentation in any way. LINQ to XMLLINQ to XML 中,如果您在載入或剖析 XML 時保留空白字元,並在序列化 XML 時停用格式化,您就可以達到這個效果。In LINQ to XMLLINQ to XML, you can do this by preserving white space when you load or parse the XML and disabling formatting when you serialize the XML.

LINQ to XMLLINQ to XML 會將空白字元儲存為 XText 節點,而不是像 DOM 儲存為序列化的 Whitespace 節點類型。stores white space as an XText node, instead of having a specialized Whitespace node type, as the DOM does.

支援附註Support for Annotations

LINQ to XMLLINQ to XML 項目支援一組可延伸的附註。elements support an extensible set of annotations. 這在追蹤項目的其他資訊 (例如,結構描述資訊)、項目是否繫結至 UI 的相關資訊,或任何種類的應用程式專屬資訊時,相當實用。This is useful for tracking miscellaneous information about an element, such as schema information, information about whether the element is bound to a UI, or any other kind of application-specific information. 如需詳細資訊,請參閱 LINQ to XML 註釋For more information, see LINQ to XML Annotations.

支援結構描述資訊Support for Schema Information

LINQ to XMLLINQ to XML 透過 System.Xml.Schema 命名空間中的擴充方法,提供 XSD 驗證支援。provides support for XSD validation through extension methods in the System.Xml.Schema namespace. 您可以驗證 XML 樹狀是以 XSD 編譯。You can validate that an XML tree complies with an XSD. 您可以利用 Post-Schema-Validation Infoset (PSVI) 填入 XML 樹狀。You can populate the XML tree with the post-schema-validation infoset (PSVI). 如需詳細資訊,請參閱如何:使用 XSD 進行驗證ExtensionsFor more information, see How to: Validate Using XSD and Extensions.

另請參閱See also