Compartilhar via


Comparação XPath e de LINQ to XML

XPath e LINQ to XML são semelhantes em alguns aspectos. Ambos podem ser usados para ver 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 de um atributo. Contudo, há diferenças significativas entre as duas opções.

Diferenças entre o XPath e o LINQ to XML

O XPath não permite a projeção de novos tipos. Somente é possível retornar coleções de nós de árvore, enquanto o 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 no isolamento dentro de uma cadeia de caracteres. O compilador do C# não pode ajudar a analisar a expressão XPath em tempo de compilação. Por outro lado, as consultas do LINQ to XML são analisadas e compiladas pelo compilador do C#. O compilador pode capturar muitos erros de consulta.

Os resultados do XPath não são fortemente tipados. Em inúmeras circunstâncias, o resultado para avaliar uma expressão XPath é um objeto, e cabe ao desenvolvedor determinar o tipo apropriado 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 resultado

A recomendação do XPath 1.0 declara que uma coleção resultante 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. Este é o caso mesmo quando acessando os eixos XPath onde os predicados são expressos em termos de ordem inversa de documento, como preceding e preceding-sibling.

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

O eixo LINQ to XML Ordenando
XContainer.DescendantNodes Ordem de documento
XContainer.Descendants Ordem de documento
XContainer.Elements Ordem de documento
XContainer.Nodes Ordem de documento
XContainer.NodesAfterSelf Ordem de documento
XContainer.NodesBeforeSelf Ordem de documento
XElement.AncestorsAndSelf Ordem inversa de documento
XElement.Attributes Ordem de documento
XElement.DescendantNodesAndSelf Ordem de documento
XElement.DescendantsAndSelf Ordem de documento
XNode.Ancestors Ordem inversa de documento
XNode.ElementsAfterSelf Ordem de documento
XNode.ElementsBeforeSelf Ordem de documento
XNode.NodesAfterSelf Ordem de documento
XNode.NodesBeforeSelf Ordem de 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-sibling, ancestor e ancestor-or-self. Por exemplo, a expressão XPath preceding-sibling::*[1] retorna imediatamente antes o irmão. Este é o caso mesmo que o conjunto de resultados final é apresentado na ordem de documento.

Por outro lado, todos os predicados posicionais em LINQ to XML sempre são expressos em termos de pedido 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ê desejar localizar imediatamente o elemento precedente no LINQ to XML, escreva a expressão a seguir:

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

Diferenças de desempenho

As consultas XPath que usam a funcionalidade do XPath no LINQ to XML não serão tão bem executadas como as consultas do LINQ to XML.

Comparação de composição

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

Por exemplo, caso tenha um elemento em uma variável nomeada como customers e você queira localizar um elemento de neto nomeado como CompanyName em todos os elementos filho nomeados como Customer, escreva uma expressão XPath como segue:

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

A consulta do LINQ to XML equivalente é:

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

Há paralelas semelhantes para cada um dos eixos XPath.

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

ou

XElement.Attributes
o eixo de ancestral XNode.Ancestors
o eixo de antepassado-ou- auto XElement.AncestorsAndSelf
o 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.