XPath と LINQ to XML の比較
XPath と LINQ to XML は、いくつかの点で似ています。 どちらも XML ツリーに対してクエリを実行するために使用され、結果として、要素のコレクション、属性のコレクション、ノードのコレクション、要素や属性の値などを返します。 ただし、この 2 つのオプションには、大きな違いがあります。
XPath と LINQ to XML の違い
XPath では、新しい型を射影できません。 XPath では、ツリーからノードのコレクションが返されるだけですが、LINQ to XML では、クエリを実行し、オブジェクト グラフまたは XML ツリーを新しい構造に射影できます。 LINQ to XML クエリは、XPath 式よりもはるかに多くのことができます。
XPath 式は、文字列内に独立して存在します。 C# コンパイラは、コンパイル時に XPath 式を解析できません。 一方 LINQ to XML クエリは、C# コンパイラによって解析され、コンパイルされます。 コンパイラによって、多くのクエリ エラーをキャッチできます。
XPath の結果は厳密に型指定されません。 多くの場合、XPath 式を評価した結果はオブジェクトであり、開発者が適切な型を決定し、必要に応じて結果をキャストする必要があります。 一方、LINQ to XML クエリからの射影は厳密に型指定されます。
結果の順序付け
XPath 1.0 勧告には、XPath 式の評価結果であるコレクションは順序付けされないことが記載されています。
ただし、LINQ to XML の XPath 軸メソッドから返されるコレクションを反復処理すると、コレクション内のノードがドキュメント順に返されます。 これは、ドキュメントの逆順として述語が表現されている preceding
や preceding-sibling
などの XPath 軸にアクセスする場合でも同様です。
これに対し、LINQ to XML 軸のほとんどは、ドキュメント順にコレクションを返します。 ただし、これらのうち 2 つ (Ancestors と AncestorsAndSelf) は、ドキュメントの逆順でコレクションを返します。 次の表では、軸を列挙し、それぞれのコレクションの順序を示します。
LINQ to XML 軸 | 並べ替え |
---|---|
XContainer.DescendantNodes | ドキュメント順 |
XContainer.Descendants | ドキュメント順 |
XContainer.Elements | ドキュメント順 |
XContainer.Nodes | ドキュメント順 |
XContainer.NodesAfterSelf | ドキュメント順 |
XContainer.NodesBeforeSelf | ドキュメント順 |
XElement.AncestorsAndSelf | ドキュメントの逆順 |
XElement.Attributes | ドキュメント順 |
XElement.DescendantNodesAndSelf | ドキュメント順 |
XElement.DescendantsAndSelf | ドキュメント順 |
XNode.Ancestors | ドキュメントの逆順 |
XNode.ElementsAfterSelf | ドキュメント順 |
XNode.ElementsBeforeSelf | ドキュメント順 |
XNode.NodesAfterSelf | ドキュメント順 |
XNode.NodesBeforeSelf | ドキュメント順 |
位置述語
XPath 式では、多くの軸で位置述語がドキュメント順として表現されますが、逆方向軸の場合は、ドキュメントの逆順で表現されます。 逆方向軸は、preceding
、preceding-sibling
、ancestor
、ancestor-or-self
です。 たとえば、XPath 式 preceding-sibling::*[1]
は、直前の兄弟を返します。 これは、最終的な結果セットがドキュメント順で表される場合も同様です。
一方、LINQ to XML の位置述語は、常に軸の順序として表現されます。 たとえば、anElement.ElementsBeforeSelf().ElementAt(0)
は、直前の兄弟ではなく、クエリされる要素の親の最初の子要素を返します。 別の例として、anElement.Ancestors().ElementAt(0)
は親要素を返します。
LINQ to XML で直前の要素を検索する場合は、次の式を記述します。
ElementsBeforeSelf().Last()
ElementsBeforeSelf().Last()
パフォーマンスの違い
LINQ to XML 内の XPath 機能を使用する XPath クエリは、LINQ to XML クエリよりも遅くなります。
構成の比較
LINQ to XML クエリの構成は、XPath 式の構成に似ていますが、構文は大きく異なります。
たとえば、customers
という変数に要素があり、Customer
というすべての子要素の下で CompanyName
という孫要素を検索する場合は、次のようにこの XPath 式を記述します。
customers.XPathSelectElements("./Customer/CompanyName")
customers.XPathSelectElements("./Customer/CompanyName")
同等の LINQ to XML クエリは次のとおりです。
customers.Elements("Customer").Elements("CompanyName")
customers.Elements("Customer").Elements("CompanyName")
同様の対応関係が XPath 軸ごとに存在します。
XPath 軸 | LINQ to XML 軸 |
---|---|
child (既定の軸) | XContainer.Elements |
Parent (..) | XObject.Parent |
attribute 軸 (@) | XElement.Attribute or XElement.Attributes |
ancestor 軸 | XNode.Ancestors |
ancestor-or-self 軸 | XElement.AncestorsAndSelf |
descendant 軸 (//) | XContainer.Descendants 、または XContainer.DescendantNodes |
descendant-or-self | XElement.DescendantsAndSelf 、または XElement.DescendantNodesAndSelf |
following-sibling | XNode.ElementsAfterSelf 、または XNode.NodesAfterSelf |
preceding-sibling | XNode.ElementsBeforeSelf or XNode.NodesBeforeSelf |
following | 同等の軸はありません。 |
preceding | 同等の軸はありません。 |
.NET