Consultas compiladas de forma estática

Una de las ventajas de rendimiento más importantes de LINQ to XML, a diferencia de XmlDocument, es que las consultas LINQ to XML se compilan estáticamente, mientras que las consultas XPath deben interpretarse durante la ejecución.Esta característica está incorporada en LINQ to XML, de modo que no tiene que efectuar pasos adicionales para aprovecharla, pero resulta útil comprender la distinción a la hora de elegir entre las dos tecnologías.Este tema explica la diferencia.

Comparación de consultas compiladas de forma estática yXPath

En el ejemplo siguiente se muestra cómo obtener los elementos descendientes con un nombre especificado y con un atributo con un valor especificado.

A continuación figura la expresión XPath equivalente:

//Address[@Type='Shipping']
XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
    from el in po.Descendants("Address")
    where (string)el.Attribute("Type") == "Shipping"
    select el;

foreach (XElement el in list1)
    Console.WriteLine(el);
Dim po = XDocument.Load("PurchaseOrders.xml")

Dim list1 = From el In po.Descendants("Address")
            Where el.@Type = "Shipping"

For Each el In list1
    Console.WriteLine(el)
Next

El compilador reescribe la expresión de consulta de este ejemplo con la sintaxis de consulta basada en métodos.En el ejemplo siguiente, que está escrito en la sintaxis de consulta basada en métodos, se producen los mismos resultados que en el anterior:

XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
    po
    .Descendants("Address")
    .Where(el => (string)el.Attribute("Type") == "Shipping");

foreach (XElement el in list1)
    Console.WriteLine(el);
Dim po = XDocument.Load("PurchaseOrders.xml")

Dim list1 As IEnumerable(Of XElement) = po.Descendants("Address").Where(Function(el) el.@Type = "Shipping")

For Each el In list1
    Console.WriteLine(el)
Next 

El método Where es una extensión del método.Para obtener más información, vea Métodos de extensión (Guía de programación de C#).Dado que Where es un método de extensión, la consulta anterior se compila como si estuviera escrita como se muestra a continuación:

XDocument po = XDocument.Load("PurchaseOrders.xml");

IEnumerable<XElement> list1 =
    System.Linq.Enumerable.Where(
        po.Descendants("Address"),
        el => (string)el.Attribute("Type") == "Shipping");

foreach (XElement el in list1)
    Console.WriteLine(el);
Dim po = XDocument.Load("PurchaseOrders.xml")

Dim list1 = Enumerable.Where(po.Descendants("Address"), Function(el) el.@Type = "Shipping")

For Each el In list1
    Console.WriteLine(el)
Next

Este ejemplo produce exactamente los mismos resultados que los dos ejemplos anteriores.Esto ilustra el hecho de que las consultas se compilan de forma efectiva en llamadas a método vinculadas estáticamente.Esto, combinado con la semántica de ejecución aplazada de los iteradores, mejora el rendimiento.Para obtener más información sobre la semántica de ejecución aplazada de los iteradores, vea Ejecución aplazada y evaluación diferida en LINQ to XML.

[!NOTA]

Estos ejemplos son representativos del código que el compilador podría escribir.La implementación real podría diferir ligeramente de estos ejemplos, pero el rendimiento será el mismo o similar a estos ejemplos.

Ejecutar expresiones XPath con XmlDocument

En el ejemplo de código siguiente se usa XmlDocument para lograr los mismos resultados que en los ejemplos anteriores:

XmlReader reader = XmlReader.Create("PurchaseOrders.xml");
XmlDocument doc = new XmlDocument();
doc.Load(reader);
XmlNodeList nl = doc.SelectNodes(".//Address[@Type='Shipping']");
foreach (XmlNode n in nl)
    Console.WriteLine(n.OuterXml);
reader.Close();
Dim reader = Xml.XmlReader.Create("PurchaseOrders.xml")
Dim doc As New Xml.XmlDocument()
doc.Load(reader)
Dim nl As Xml.XmlNodeList = doc.SelectNodes(".//Address[@Type='Shipping']")
For Each n As Xml.XmlNode In nl
    Console.WriteLine(n.OuterXml)
Next
reader.Close()

Esta consulta devuelve el mismo resultado que los ejemplos que usan LINQ to XML; la única diferencia es que LINQ to XML aplica sangría al XML impreso, mientras que XmlDocument no.

No obstante, el enfoque de XmlDocument generalmente no funciona tan bien como LINQ to XML, porque el método SelectNodes debe realizar lo siguiente internamente cada vez que se le llama:

  • Analiza la cadena que contiene la expresión XPath, y divide la cadena en tokens.

  • Valida los tokens para asegurarse de que la expresión XPath es válida.

  • Traduce la expresión a un árbol de expresión interno.

  • Recorre en iteración los nodos, y selecciona de forma adecuada los nodos del conjunto de resultados basándose en la evaluación de la expresión.

Esto es bastante más que el trabajo realizado por la consulta LINQ to XML correspondiente.La diferencia de rendimiento específica varía para distintos tipos de consultas, pero en general las consultas LINQ to XML efectúan menos operaciones y, por lo tanto, se ejecutan mejor, que si se evalúan las expresiones XPath con XmlDocument.

Vea también

Conceptos

Rendimiento (LINQ to XML)