Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Una de las ventajas de rendimiento más importantes de LINQ to XML, en comparación con XmlDocument, es que las consultas de LINQ to XML se compilan estáticamente, mientras que las consultas XPath deben interpretarse en tiempo de ejecución. Esta característica está integrada en LINQ to XML, por lo que no es necesario realizar pasos adicionales para aprovecharlo, pero resulta útil comprender la distinción al elegir entre las dos tecnologías. En este artículo se explica la diferencia.
Consultas compiladas estáticamente frente a XPath
En el ejemplo siguiente se muestra cómo obtener los elementos descendientes con un nombre especificado y con un atributo con un valor especificado. La expresión XPath equivalente es //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 vuelve a escribir la expresión de consulta de este ejemplo en la sintaxis de consulta basada en métodos. En el ejemplo siguiente, que se escribe en la sintaxis de consulta basada en métodos, se generan los mismos resultados que 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 Where método es un método de extensión. 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 de la siguiente manera:
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
En este ejemplo se generan exactamente los mismos resultados que los dos ejemplos anteriores. Esto ilustra el hecho de que las consultas se compilan de forma eficaz en llamadas de método vinculadas estáticamente. Esto, combinado con la semántica de ejecución diferida de iteradores, mejora el rendimiento. Para obtener más información sobre la semántica de ejecución diferida de iteradores, vea Ejecución diferida y evaluación diferida.
Nota:
Estos ejemplos son representativos del código que el compilador podría escribir. La implementación real puede diferir ligeramente de estos ejemplos, pero el rendimiento será el mismo que, o similar a, estos ejemplos.
Ejecución de expresiones XPath con XmlDocument
En el ejemplo siguiente se usa XmlDocument para lograr los mismos resultados que 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.
Sin embargo, el XmlDocument enfoque generalmente no funciona tan bien como LINQ to XML, ya que el SelectNodes método debe hacer lo siguiente cada vez que se llama:
- Analice la cadena que contiene la expresión XPath y divida la cadena en tokens.
- Valide los tokens para asegurarse de que la expresión XPath es válida.
- Traduzca la expresión en un árbol de expresiones interno.
- Recorrer en iteración los nodos, seleccionando adecuadamente los nodos del conjunto de resultados en función de la evaluación de la expresión.
Esto es significativamente más que el trabajo realizado por la consulta LINQ to XML correspondiente. La diferencia de rendimiento específica varía para los distintos tipos de consultas, pero en general las consultas LINQ to XML realizan menos trabajo y, por lo tanto, funcionan mejor que evaluar expresiones XPath mediante XmlDocument.