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. 関数型構築では、XElement コンストラクターと XAttribute コンストラクターを使用して XML ツリーを構築します。Functional construction uses the XElement and XAttribute constructors to build an XML tree.

上記の例と同じ XML ツリーを LINQ to XMLLINQ to 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 要素と 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.

  • T:System.Xml.Linq.XElement オブジェクトを直接 XML ファイルから読み込む。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 ドキュメントが XML ツリーの論理的コンテナーとして使用される W3C DOM では、Compare this to the W3C DOM, in which the XML document is used as a logical container for the XML tree. XML ノード (要素や属性を含む) は XML ドキュメントのコンテキストで作成する必要があります。In DOM, XML nodes, including elements and attributes, must be created in the context of an XML document. DOM で name 要素を作成するコード フラグメントを以下に示します。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. 詳細については、「XML 名前空間の使用 (C#)」を参照してください。For more information, see Working with XML Namespaces (C#).

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.

XPathNavigator のサポートSupport 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.Extensions」を参照してください。For 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.

もう 1 つのよくあるシナリオは、意図的にインデントされた 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. また、スキーマ検証後の情報セット (PSVI) を使用して XML ツリーを設定できます。You can populate the XML tree with the post-schema-validation infoset (PSVI). 詳細については、「方法 :XSD を使用して検証する」と Extensions を参照してください。For more information, see How to: Validate Using XSD and Extensions.

関連項目See also