XDocument o XmlDocument

504

Ahora estoy aprendiendo, XmlDocumentpero me acabo de encontrar XDocumenty cuando trato de buscar la diferencia o los beneficios de ellos no puedo encontrar algo útil, ¿podría decirme por qué usaría uno sobre otro?

Tarik
fuente
13
Me pregunto por qué los chicos de documentación en Microsoft no pusieron ninguna nota o comentario en MSDN para aclarar sus diferencias o cuándo usar qué.
Kamran Bigdely
1
Alguna información sobre msdn: msdn.microsoft.com/en-us/library/… . Y una pregunta de rendimiento: stackoverflow.com/questions/4383919/… . Personalmente, me ha resultado más fácil trabajar con LINQ to XML.
nawfal

Respuestas:

501

Si está utilizando .NET versión 3.0 o inferior, tiene que usar XmlDocumenttambién conocido como el API DOM clásico. Del mismo modo, encontrará que hay otras API que esperarán esto.

Sin embargo, si tiene la opción, le recomendaría usar XDocumenttambién aka LINQ to XML. Es mucho más simple crear documentos y procesarlos. Por ejemplo, es la diferencia entre:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("root");
root.SetAttribute("name", "value");
XmlElement child = doc.CreateElement("child");
child.InnerText = "text node";
root.AppendChild(child);
doc.AppendChild(root);

y

XDocument doc = new XDocument(
    new XElement("root",
                 new XAttribute("name", "value"),
                 new XElement("child", "text node")));

Los espacios de nombres son bastante fáciles de trabajar en LINQ to XML, a diferencia de cualquier otra API XML que haya visto:

XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc

LINQ to XML también funciona muy bien con LINQ: su modelo de construcción le permite construir elementos con secuencias de subelementos con mucha facilidad:

// Customers is a List<Customer>
XElement customersElement = new XElement("customers",
    customers.Select(c => new XElement("customer",
        new XAttribute("name", c.Name),
        new XAttribute("lastSeen", c.LastOrder)
        new XElement("address",
            new XAttribute("town", c.Town),
            new XAttribute("firstline", c.Address1),
            // etc
    ));

Todo es mucho más declarativo, lo que encaja con el estilo general de LINQ.

Ahora, como mencionó Brannon, estas son API en memoria en lugar de las de transmisión (aunque XStreamingElementadmite salida diferida). XmlReadery XmlWriterson las formas normales de transmisión de XML en .NET, pero puede mezclar todas las API hasta cierto punto. Por ejemplo, puede transmitir un documento grande pero usar LINQ to XML colocando un XmlReaderal comienzo de un elemento, leyendo uno XElementy procesándolo, luego pasando al siguiente elemento, etc. Hay varias publicaciones de blog sobre esta técnica, Aquí hay uno que encontré con una búsqueda rápida .

Jon Skeet
fuente
¿Podrías decirme por qué son diferentes? Quiero decir, sí, XDocument se ve bastante ordenado, pero en cuanto a la diferencia de nivel DOM, ¿no son ambos xml? ¿Hay algún esquema que muestre tanto DOM X-DOM de Microsoft como DOM que cumplan con W3C? Gracias.
Tarik
3
¿Qué quieres decir con "esquema" y qué quieres decir con "espectáculos"? Sí, ambos tratan con XML estándar, pero LINQ to XML es una API más agradable para la mayoría de las cosas. Mucha de la tecnología detrás de LINQ to XML simplemente no estaba disponible antes de .NET 3.5.
Jon Skeet
Quiero decir si sus modelos de objetos de documento son diferentes.
Tarik
66
Bueno, ambas son API para XML, por lo que en ese sentido no son diferentes, no. Sospecho que ambos tienen algunas limitaciones (y hay un LINQ to XML que conozco pero que no recuerdo bien), pero en la mayoría de los casos puedes tratarlos como si fueran el mismo modelo con representaciones ligeramente diferentes.
Jon Skeet
1
@SensorSmith: Sin embargo, eso no cubre todas las otras bonificaciones, como el aplanamiento automático de secuencias, el manejo de DateTime, etc. También podría agregar métodos de extensiones para todo eso, pero ¿por qué reinventar LINQ to XML cuando solo puede usarlo?
Jon Skeet
57

Me sorprende que ninguna de las respuestas hasta ahora mencione el hecho de que XmlDocumentno proporciona información de línea , mientras que XDocument (a través de la IXmlLineInfointerfaz).

Esta puede ser una característica crítica en algunos casos (por ejemplo, si desea informar errores en un XML, o realizar un seguimiento de dónde se definen los elementos en general) y es mejor que esté al tanto de esto antes de comenzar a implementarlo XmlDocument, para más adelante descubre que tienes que cambiarlo todo.

Julien Guertault
fuente
1
Y me sorprende que nadie haya notado que su afirmación es inversamente cierta. XmlDocument SÍ proporciona la información de línea mientras que XDocument no.
VVS
44
@VVS: por un momento me preocupé de haber cometido un error tipográfico terrible, pero después de una doble verificación, confirmo que XDocumentsí proporciona información de línea. Ver XDocument.Load with LoadOptions.SetLineInfocomo segundo argumento. Si conoces una forma de obtener información de línea, XmlDocumenttengo curiosidad; cuando escribí esta respuesta no pude encontrar ninguna. Esta otra respuesta parece confirmar: stackoverflow.com/a/33622102/253883
Julien Guertault
1
"y es mejor que se dé cuenta de esto antes de comenzar a implementar felizmente usando XmlDocument, para luego descubrir que tiene que cambiarlo todo". Adivina lo que acabo de hacer :)
Paul
36

XmlDocumentes ideal para desarrolladores que están familiarizados con el modelo de objetos DOM XML. Ha existido por un tiempo, y más o menos corresponde a un estándar W3C. Es compatible con la navegación manual, así como la XPathselección de nodos.

XDocumentalimenta la característica LINQ to XML en .NET 3.5. Hace un uso intensivo IEnumerable<>y puede ser más fácil trabajar con él en C # directo.

Ambos modelos de documentos requieren que cargue todo el documento en la memoria (a diferencia de, XmlReaderpor ejemplo).

Brannon
fuente
3
Creo que quiso decir "y puede ser más fácil trabajar en VB.net". Porque VB admite la creación directa de elementos donde C # todavía requiere código.
Brain2000
24

Como se mencionó en otra parte, sin duda, Linq to Xml hace que la creación y alteración de documentos xml sea muy fácil en comparación con XmlDocument, y la XNamespace ns + "elementName"sintaxis permite una lectura placentera cuando se trata de espacios de nombres.

Una cosa que vale la pena mencionar xsly xpathque es difícil notar es que aún es posible ejecutar xpath 1.0expresiones arbitrarias en Linq 2 Xml XNodesal incluir:

using System.Xml.XPath;

y luego podemos navegar y proyectar datos usando xpathestos métodos de extensión:

Por ejemplo, dado el documento Xml:

<xml>
    <foo>
        <baz id="1">10</baz>
        <bar id="2" special="1">baa baa</bar>
        <baz id="3">20</baz>
        <bar id="4" />
        <bar id="5" />
    </foo>
    <foo id="123">Text 1<moo />Text 2
    </foo>
</xml>

Podemos evaluar:

var node = xele.XPathSelectElement("/xml/foo[@id='123']");
var nodes = xele.XPathSelectElements(
"//moo/ancestor::xml/descendant::baz[@id='1']/following-sibling::bar[not(@special='1')]");
var sum = xele.XPathEvaluate("sum(//foo[not(moo)]/baz)");
StuartLC
fuente
24

XDocumentes de la API de LINQ to XML, y XmlDocumentes la API de estilo DOM estándar para XML. Si conoce DOM bien y no quiere aprender LINQ to XML, vaya con XmlDocument. Si eres nuevo en ambos, mira esta página que compara los dos, y elige cuál te gusta más.

Acabo de comenzar a usar LINQ to XML, y me encanta la forma en que creas un documento XML utilizando la construcción funcional. Es realmente bueno. DOM es torpe en comparación.

Daniel Chambers
fuente
14

Además, tenga en cuenta que XDocumentes compatible con Xbox 360 y Windows Phone OS 7.0. Si los orienta, desarrolle XDocumento migre desde XmlDocument.

w0land
fuente
-8

Creo que eso XDocumenthace muchas más llamadas de creación de objetos. Sospecho que cuando manejas muchos documentos XML,XMLDocument será más rápido.

Un lugar donde esto sucede es en la gestión de los datos escaneados. Muchas herramientas de escaneo generan sus datos en XML (por razones obvias). Si tiene que procesar muchos de estos archivos de escaneo, creo que tendrá un mejor rendimiento XMLDocument.

Brian
fuente
11
Creo que la próxima vez deberías respaldar tu comentario con cifras, ya que creo que puedes estar equivocado. Ver blogs.msdn.com/b/codejunkie/archive/2008/10/08/…
mike