Compartir a través de


Comparación de XPath y LINQ to XML

Actualización: November 2007

XPath y LINQ to XML ofrecen una funcionalidad similar. Ambos se pueden usar para consultar un árbol XML, devolviendo resultados como una recopilación de elementos, una recopilación de nodos o el valor de un elemento o atributo. Sin embargo, también hay algunas diferencias.

Diferencias entre XPath y LINQ to XML

XPath no permite la proyección de nuevos tipos. Sólo puede devolver recopilaciones de nodos del árbol, mientras que LINQ to XML puede ejecutar una consulta y proyectar un gráfico de objetos o un árbol XML en una nueva forma. Las consultas de LINQ to XML abarcan una funcionalidad mucho mayor y son mucho más eficaces que las expresiones XPath.

Las expresiones XPath existen de forma aislada en una cadena. El compilador de C# o Visual Basic no puede ayudar a analizar la expresión XPath en tiempo de compilación. Por el contrario, el compilador de C# o Visual Basic analiza y compila las consultas de LINQ to XML. El compilador puede detectar muchos errores de consulta.

Los resultados de XPath no tienen un establecimiento inflexible de tipos. En varias circunstancias, el resultado de evaluar una expresión XPath es un objeto, y depende del desarrollador determinar el tipo adecuado y convertir el resultado según sea necesario. Por el contrario, las proyecciones de una consulta de LINQ to XML tienen un establecimiento inflexible.

Ordenación de resultados

La recomendación XPath 1.0 indica que una recopilación que es el resultado de evaluar una expresión XPath está desordenada.

No obstante, cuando se recorre en iteración una recopilación devuelta por un método de eje XPath de LINQ to XML, los nodos de la recopilación se devuelven en el orden del documento. Esto es aplicable incluso cuando se tiene acceso a los ejes XPath donde se expresan los predicados en términos de orden de documento inverso, como preceding y preceding-sibling.

Por el contrario, la mayoría de los ejes de LINQ to XML devuelven recopilaciones en el orden del documento, pero dos de ellos, Ancestors y AncestorsAndSelf, devuelven recopilaciones en el orden inverso del documento. En la siguiente tabla se enumeran los ejes y se indica el orden de la recopilación para cada uno:

Eje LINQ to XML

Ordenación

XContainer.DescendantNodes

Orden del documento

XContainer.Descendants

Orden del documento

XContainer.Elements

Orden del documento

XContainer.Nodes

Orden del documento

XContainer.NodesAfterSelf

Orden del documento

XContainer.NodesBeforeSelf

Orden del documento

XElement.AncestorsAndSelf

Orden del documento inverso

XElement.Attributes

Orden del documento

XElement.DescendantNodesAndSelf

Orden del documento

XElement.DescendantsAndSelf

Orden del documento

XNode.Ancestors

Orden del documento inverso

XNode.ElementsAfterSelf

Orden del documento

XNode.ElementsBeforeSelf

Orden del documento

XNode.NodesAfterSelf

Orden del documento

XNode.NodesBeforeSelf

Orden del documento

Predicados de posición

En una expresión XPath, los predicados de posición se expresan en términos de orden del documento para muchos ejes, pero se expresan en el orden del documento inverso para los ejes inversos, que son preceding, preceding-sibling, ancestor y ancestor-or-self. Por ejemplo, la expresión de XPath preceding-sibling::*[1] devuelve el elemento del mismo nivel inmediatamente anterior. Esto es aplicable aunque el conjunto de resultados finales se presenta en el orden del documento.

Por el contrario, todos los predicados de posición de LINQ to XML siempre se expresan en términos del orden del eje. Por ejemplo, anElement.ElementsBeforeSelf().ToList()[0] devuelve el primer elemento secundario del elemento primario del elemento consultado, no el elemento del mismo nivel inmediatamente anterior. Otro ejemplo: anElement.Ancestors().ToList()[0] devuelve el elemento primario.

Tenga en cuenta que el enfoque anterior materializa toda la recopilación. Ésta no es la forma más eficiente de escribir esa consulta. Se ha escrito de esa forma para demostrar el comportamiento de los predicados de posición. Una forma más adecuada de escribir la misma consulta es usar el método First de la siguiente manera: anElement.ElementsBeforeSelf().First().

Si deseara buscar el elemento inmediatamente precedente de LINQ to XML escribiría la siguiente expresión:

ElementsBeforeSelf().Last()

Diferencias de rendimiento

Las consultas de XPath que usan la funcionalidad en XPath LINQ to XML no tienen un rendimiento tan bueno como las consultas de LINQ to XML.

Comparación de la composición

La composición de una consulta de LINQ to XML es en cierta medida paralela a la composición de una expresión XPath, aunque tiene una sintaxis muy diferente.

Por ejemplo, si tiene un elemento de una variable con el nombre customers y desea buscar un elemento inferior con el nombre CompanyName bajo todos los elementos secundarios con el nombre Customer, debe escribir una expresión XPath de la siguiente manera:

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

La consulta de LINQ to XML equivalente es:

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

Existen elementos similares para cada uno de los ejes XPath.

Eje XPath

Eje LINQ to XML

secundario (el eje predeterminado)

XContainer.Elements

Primario (..)

XObject.Parent

eje de atributo (@)

XElement.Attribute

o bien

XElement.Attributes

eje antecesor

XNode.Ancestors

eje antecesor o propio

XElement.AncestorsAndSelf

eje descendiente (//)

XContainer.Descendants

o bien

XContainer.DescendantNodes

descendiente o propio

XElement.DescendantsAndSelf

o bien

XElement.DescendantNodesAndSelf

siguientes-relacionados

XNode.ElementsAfterSelf

o bien

XNode.NodesAfterSelf

precedentes-relacionados

XNode.ElementsBeforeSelf

o bien

XNode.NodesBeforeSelf

siguientes

No hay equivalente directo.

precedentes

No hay equivalente directo.

Vea también

Conceptos

LINQ to XML para usuarios de XPath