XPath 和 LINQ to XML 的比較
XPath 和 LINQ to XML 提供一些類似的功能。兩者都可用於查詢 XML 樹狀結構,將此類結果當做項目的集合、屬性的集合、節點的集合,以及項目或屬性的值傳回。不過,也有一些差異。
XPath 與 LINQ to XML 之間的差異
XPath 不允許評估新的型別。它只能從樹狀結構傳回節點的集合,而 LINQ to XML 可以執行查詢並評估新圖案中的物件圖形或 XML 樹狀結構。LINQ to XML 查詢包含的功能更多,而且比 XPath 運算式的功能更強大。
XPath 運算式存在於字串內的隔離中。C# 或 Visual Basic 編譯器在編譯時期無法協助剖析 XPath 運算式。相較之下,C# 或 Visual Basic 編譯器不會剖析與編譯 LINQ to XML 查詢。該編譯器可以擷取許多查詢錯誤。
XPath 結果不是強型別 (Strongly Typed)。在許多情況下,評估 XPath 運算式的結果不是物件,而且開發人員可以決定適當的型別,並在必要時轉換結果。相較之下,LINQ to XML 查詢的評估為強型別。
結果順序
XPath 1.0 建議事項說明評估 XPath 運算式之結果的集合沒有排序。
不過,逐一查看由 LINQ to XML XPath 軸方法傳回的集合時,會以文件順序傳回集合中的節點。即使在存取 XPath 軸 (其中的述詞會根據反向的文件順序表示,例如,preceding 和 preceding-sibling) 時,也是如此。
相較之下,大部分的 LINQ to XML 軸會以文件順序傳回集合,但其中兩個 (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().ToList()[0] 會傳回所查詢項目之父代的第一個子項目,而非正前面的同層級。另一個範例:anElement.Ancestors().ToList()[0] 會傳回父項目。
請注意,上述的方法會具體化整個集合。這不是撰寫該查詢的最有效方式。此範例以該方式撰寫,以示範位置性述詞的行為。撰寫相同查詢更適當的方式為使用 First 方法,如下所示:anElement.ElementsBeforeSelf().First()。
如果您要在 LINQ to XML 中尋找正前面的項目,您可以撰寫下列運算式:
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.Element("Customer").Elements("CompanyName");
customers.Element("Customer").Elements("CompanyName")
每個 XPath 座標軸都有類似的項目。
XPath 座標軸 |
LINQ to XML 座標軸 |
---|---|
child (預設座標軸) |
|
Parent (..) |
|
attribute 座標軸 (@) |
或 |
ancestor 座標軸 |
|
ancestor-or-self 座標軸 |
|
descendant 座標軸 (//) |
或 |
descendant-or-self |
或 |
following-sibling |
或 |
preceding-sibling |
或 |
following |
沒有直接的對等。 |
preceding |
沒有直接的對等。 |