Compartilhar via


Comparação de XPath e LINQ com XML

XPath e LINQ to XML são semelhantes em alguns aspectos. Ambos podem ser usados para consultar uma árvore XML, retornando resultados como uma coleção de elementos, uma coleção de atributos, uma coleção de nós ou o valor de um elemento ou atributo. No entanto, há diferenças significativas entre as duas opções.

Diferenças entre XPath e LINQ to XML

O XPath não permite a projeção de novos tipos. Ele só pode retornar coleções de nós da árvore, enquanto LINQ to XML pode executar uma consulta e projetar um grafo de objeto ou uma árvore XML em uma nova forma. Consultas LINQ to XML podem fazer muito mais do que expressões XPath.

As expressões XPath existem isoladamente dentro de uma cadeia de caracteres. O compilador C# não pode ajudar a analisar a expressão XPath em tempo de compilação. Por outro lado, as consultas LINQ to XML são analisadas e compiladas pelo compilador C#. O compilador pode capturar muitos erros de consulta.

Os resultados do XPath não são fortemente tipados. Em várias circunstâncias, o resultado da avaliação de uma expressão XPath é um objeto e cabe ao desenvolvedor determinar o tipo adequado e converter o resultado conforme necessário. Por outro lado, as projeções de uma consulta do LINQ to XML são fortemente tipadas.

Ordenação de resultados

A recomendação XPath 1.0 afirma que uma coleção que é o resultado da avaliação de uma expressão XPath não é ordenada.

Entretanto, ao fazer iterações por uma coleção retornada por um método do eixo XPath do LINQ to XML, os nós na coleção são retornados na ordem do documento. Esse é o caso mesmo ao acessar os eixos XPath em que os predicados são expressos em termos de ordem de documento inversa, como preceding e preceding-sibling.

Por outro lado, a maioria dos eixos do LINQ to XML retorna coleções na sequência do documento. No entanto, duas delas, Ancestors e AncestorsAndSelf, retornam coleções em ordem de documento inversa. A tabela a seguir enumera os eixos e indica a ordem de coleta para cada um:

O eixo LINQ to XML Pedido
XContainer.DescendantNodes Ordem do documento
XContainer.Descendants Ordem do documento
XContainer.Elementos Ordem do documento
XContainer.Nodes Ordem do documento
XContainer.NodesAfterSelf Ordem do documento
XContainer.NodesBeforeSelf Ordem do documento
XElement.AncestorsAndSelf Inverter a ordem dos documentos
XElement.Attributes Ordem do documento
XElement.DescendantNodesAndSelf Ordem do documento
XElement.DescendantsAndSelf Ordem do documento
XNode.Ancestors Inverter a ordem dos documentos
XNode.ElementsAfterSelf Ordem do documento
XNode.ElementsBeforeSelf Ordem do documento
XNode.NodesAfterSelf Ordem do documento
XNode.NodesBeforeSelf Ordem do documento

Predicados posicionais

Em uma expressão XPath, os predicados posicionais são expressos em termos de pedido de documento para muitos eixos, mas expressos na ordem inversa de documento para os eixos invertidos. Os eixos inversos são: preceding, , preceding-siblinge ancestorancestor-or-self. Por exemplo, a expressão XPath preceding-sibling::*[1] retorna imediatamente antes o irmão. Esse é o caso, embora o conjunto de resultados final seja apresentado na ordem do documento.

Por outro lado, todos os predicados posicionais em LINQ to XML são sempre expressos em termos da ordem do eixo. Por exemplo, anElement.ElementsBeforeSelf().ElementAt(0) retorna o primeiro elemento filho do pai do elemento consultado, não irmão anterior imediato. Outro exemplo: anElement.Ancestors().ElementAt(0) retorna o elemento pai.

Se você quisesse encontrar o elemento imediatamente anterior no LINQ to XML, escreveria a seguinte expressão:

ElementsBeforeSelf().Last()
ElementsBeforeSelf().Last()

Diferenças de desempenho

As consultas XPath que usam a funcionalidade XPath no LINQ to XML serão mais lentas do que as consultas LINQ to XML.

Comparação de composição

A composição de uma consulta LINQ to XML é semelhante à composição de uma expressão XPath, mas a sintaxe é muito diferente.

Por exemplo, se você tiver um elemento em uma variável chamada customers, e quiser encontrar um elemento neto nomeado CompanyName sob todos os elementos filho nomeados Customer, você escreverá esta expressão XPath:

customers.XPathSelectElements("./Customer/CompanyName")
customers.XPathSelectElements("./Customer/CompanyName")

A consulta LINQ to XML equivalente é:

customers.Elements("Customer").Elements("CompanyName")
customers.Elements("Customer").Elements("CompanyName")

Há paralelos semelhantes para cada um dos eixos XPath.

Eixo XPath O eixo LINQ to XML
o eixo filho (padrão) XContainer.Elements
Pai (..) XObject.Parent
eixo do atributo (@) XElement.Attribute

ou

XElement.Attributes
o eixo de ancestral XNode.Ancestors
o eixo de antepassado-ou- auto XElement.AncestorsAndSelf
eixo descendente (//) XContainer.Descendants

ou

XContainer.DescendantNodes
descendente-ou-auto XElement.DescendantsAndSelf

ou

XElement.DescendantNodesAndSelf
seguir-irmão XNode.ElementsAfterSelf

ou

XNode.NodesAfterSelf
acima-irmão XNode.ElementsBeforeSelf

ou

XNode.NodesBeforeSelf
após Nenhum equivalente direto.
precedência Nenhum equivalente direto.