read nodo leer especifico ejemplo create crear c# xml-serialization xmldocument xmlreader

c# - nodo - Decidir cuándo usar XmlDocument vs XmlReader



xmldocument c# ejemplo (5)

Estoy optimizando un objeto personalizado -> utilidad de serialización XML, y todo está hecho y funcionando, y ese no es el problema.

Funcionó al cargar un archivo en un objeto XmlDocument , y luego recorrer recursivamente todos los nodos secundarios.

Pensé que quizás usar XmlReader lugar de tener XmlDocument cargando / analizando todo el proceso sería más rápido, así que también implementé esa versión.

Los algoritmos son exactamente iguales. Utilizo una clase contenedora para abstraer la funcionalidad de tratar con un XmlNode vs. un XmlReader . Por ejemplo, los métodos GetChildren dan como resultado un XmlNode hijo o un SubTree XmlReader .

Así que escribí un controlador de prueba para probar ambas versiones y el uso de un conjunto de datos no triviales (un archivo XML de 900kb con alrededor de 1.350 elementos).

Sin embargo, usando JetBrains dotTRACE, veo que la versión de XmlReader es en realidad más lenta que la versión de XmlDocument . Parece que hay un procesamiento significativo involucrado en las XmlReader lectura XmlReader cuando estoy iterando sobre los nodos secundarios.

Entonces digo todo eso para preguntar esto:

¿Cuáles son las ventajas / desventajas de XmlDocument y XmlReader , y en qué circunstancias debería usar cualquiera?

XmlReader que hay un límite de tamaño de archivo en el que XmlReader vuelve más económico en rendimiento, y XmlReader menos memoria. Sin embargo, ese umbral parece estar por encima de 1MB.

ReadSubTree a ReadSubTree cada vez para procesar nodos secundarios:

public override IEnumerable<IXmlSourceProvider> GetChildren () { XmlReader xr = myXmlSource.ReadSubtree (); // skip past the current element xr.Read (); while (xr.Read ()) { if (xr.NodeType != XmlNodeType.Element) continue; yield return new XmlReaderXmlSourceProvider (xr); } }

Esa prueba se aplica a muchos objetos en un solo nivel (es decir, amplio y poco profundo), pero me pregunto qué tan bien XmlReader va a XmlReader cuando el XML es profundo y amplio. Es decir, el XML con el que trato es muy parecido a un modelo de objetos de datos, 1 objeto principal a muchos objetos secundarios, etc.: 1..M..M..M

Tampoco sé de antemano la estructura del XML que estoy analizando, por lo que no puedo optimizarlo.


Generalmente lo he visto no desde una perspectiva más rápida , sino desde una perspectiva de utilización de la memoria . Todas las implementaciones han sido lo suficientemente rápidas para los escenarios de uso en los que los he usado (integración empresarial típica).

Sin embargo, donde me he caído, y algunas veces espectacularmente, no estoy teniendo en cuenta el tamaño general del XML con el que estoy trabajando. Si lo piensas al principio puedes ahorrarte algo de dolor.

XML tiende a hincharse cuando se carga en la memoria, al menos con un lector DOM como XmlDocument o XPathDocument . Algo así como 10: 1? La cantidad exacta es difícil de cuantificar, pero si es 1 MB en el disco, será de 10 MB en la memoria, o más, por ejemplo.

Un proceso que utilice cualquier lector que cargue todo el documento en la memoria en su totalidad ( XmlDocument / XPathDocument ) puede sufrir una gran fragmentación del montón de objetos, que en última instancia puede llevar a OutOfMemoryException s (incluso con memoria disponible) dando como resultado un servicio / proceso no disponible.

Como los objetos que tienen un tamaño superior a 85 KB terminan en el gran montón de objetos, y usted tiene una explosión de tamaño 10: 1 con un lector DOM, puede ver que no se necesita mucho antes de asignar sus documentos XML desde el gran montón de objetos.

XmlDocument es muy fácil de usar. Su único inconveniente real es que carga todo el documento XML en la memoria para procesar. Es seductoramente simple de usar.

XmlReader es un lector basado en secuencias, por lo que mantendrá la utilización de la memoria de procesos generalmente más plana pero es más difícil de usar.

XPathDocument tiende a ser una versión más rápida y de solo lectura de XmlDocument, pero aún sufre de "bloat" de memoria.


Hay un umbral de tamaño en el que XmlDocument se vuelve más lento y, finalmente, inutilizable. Pero el valor real del umbral dependerá de su aplicación y del contenido XML, por lo que no existen reglas estrictas.

Si su archivo XML puede contener grandes listas (digamos decenas de miles de elementos), definitivamente debe usar XmlReader.


La diferencia de codificación se debe a que se mezclan dos medidas diferentes. UTF-32 requiere 4 bytes por carácter, y es intrínsecamente más lento que los datos de un solo byte.

Si observa la prueba de elementos grandes (100K), verá que el tiempo aumenta en aproximadamente 70 ms para cada caso, independientemente del método de carga utilizado.

Esta es una diferencia (casi) constante causada específicamente por la sobrecarga por carácter,


Otra consideración es que XMLReader podría ser más robusto para manejar XML que no está perfectamente formado. Recientemente, creé un cliente que consumía una secuencia XML, pero la transmisión no tenía los caracteres especiales escapados correctamente en los URI contenidos en algunos de los elementos. XMLDocument y XPathDocument se negaron a cargar el XML, mientras que con XMLReader pude extraer la información que necesitaba de la transmisión.


XmlDocument es una representación en memoria de todo el documento XML. Por lo tanto, si su documento es grande, consumirá mucha más memoria que si lo hubiera leído usando XmlReader.

Esto supone que cuando use XmlReader lea y procese los elementos uno a uno y luego deséchelos. Si usa XmlReader y construye otra estructura intermediaria en la memoria, entonces tiene el mismo problema, y ​​está derrotando el propósito de la misma.

Busca " SAX versus DOM " para leer más sobre la diferencia entre los dos modelos de procesamiento de XML.