Estoy tratando de leer el siguiente documento XML lo más rápido que puedo y dejar que clases adicionales administren la lectura de cada subbloque.
<ApplicationPool>
<Accounts>
<Account>
<NameOfKin></NameOfKin>
<StatementsAvailable>
<Statement></Statement>
</StatementsAvailable>
</Account>
</Accounts>
</ApplicationPool>
Sin embargo, estoy tratando de utilizar el objeto XmlReader para leer cada cuenta y, posteriormente, las "Declaraciones disponibles". ¿Sugieres usar XmlReader. Lee y verifica cada elemento y manejalo?
He pensado en separar mis clases para manejar cada nodo correctamente. Entonces, hay una clase AccountBase que acepta una instancia de XmlReader que lee el NameOfKin y varias otras propiedades sobre la cuenta. Luego quería interactuar a través de las Declaraciones y dejar que otra clase se completara sobre la Declaración (y luego agregarla a una IList).
Hasta ahora he hecho la parte "por clase" haciendo XmlReader.ReadElementString () pero no puedo entrenar cómo decirle al puntero que se mueva al elemento StatementsAvailable y déjeme iterar a través de ellos y dejar que otra clase lea cada uno de esos proeprties .
¡Suena fácil!
Respuestas:
Mi experiencia
XmlReader
es que es muy fácil leer demasiado accidentalmente. Sé que ha dicho que desea leerlo lo más rápido posible, pero ¿ha intentado utilizar un modelo DOM en su lugar? Descubrí que LINQ to XML hace que XML funcione mucho más fácilmente.Si su documento es particularmente grande, puede combinar
XmlReader
y LINQ to XML creando unXElement
desde yXmlReader
para cada uno de sus elementos "externos" en forma de transmisión: esto le permite hacer la mayor parte del trabajo de conversión en LINQ to XML, pero aún así solo necesita una pequeña parte del documento en la memoria en cualquier momento. Aquí hay un código de muestra (adaptado ligeramente de esta publicación de blog ):He usado esto para convertir los datos del usuario de StackOverflow (que es enorme) a otro formato antes; funciona muy bien.
EDITAR desde radarbob, reformateado por Jon, aunque no está del todo claro a qué problema de "lectura demasiado lejos" se hace referencia ...
Esto debería simplificar el anidamiento y solucionar el problema de "una lectura demasiado lejana".
Esto soluciona el problema de "una lectura demasiado lejana" porque implementa el patrón de bucle while clásico:
fuente
if(reader.Name == elementName)
parawhile(reader.Name == elementName)
solucionar el problema señalado por pbz?SimpleStreamAxis()
omitirá elementos cuando el XML no esté sangrado, porqueNode.ReadFrom()
coloca al lector en el siguiente nodo después de que se cargue el elemento, que será omitido por el siguiente incondicionalRead()
. Si el siguiente nodo es un espacio en blanco, entonces todo está bien. De otra forma no. Para versiones sin este problema, consulte aquí , aquí o aquí .Tres años más tarde, quizás con el énfasis renovado en WebApi y los datos xml, me encontré con esta pregunta. Desde el código, me inclino a seguir a Skeet fuera de un avión sin paracaídas, y ver su código inicial doblemente corraborado por el artículo del equipo MS Xml, así como un ejemplo en BOL Streaming Transform of Large Xml Docs , rápidamente pasé por alto los otros comentarios. , más específicamente de 'pbz', quien señaló que si tiene los mismos elementos por nombre en sucesión, todos los demás se omiten debido a la doble lectura. Y, de hecho, los artículos de los blogs de BOL y MS analizaban documentos de origen con elementos de destino anidados más profundos que el segundo nivel, enmascarando este efecto secundario.
Las otras respuestas abordan este problema. Solo quería ofrecer una revisión un poco más simple que parece funcionar bien hasta ahora y tiene en cuenta que el xml puede provenir de diferentes fuentes, no solo un uri, por lo que la extensión funciona en el XmlReader administrado por el usuario. La única suposición es que el lector está en su estado inicial, ya que de lo contrario el primer 'Read ()' podría avanzar más allá de un nodo deseado:
fuente
else Read()
aplique a ambos. Gracias por captar eso.Hacemos este tipo de análisis XML todo el tiempo. La clave es definir dónde el método de análisis dejará al lector al salir. Si siempre deja al lector en el siguiente elemento que sigue al elemento que se leyó primero, entonces puede leer de manera segura y predecible en el flujo XML. Entonces, si el lector está indexando el
<Account>
elemento, después de analizar, el lector indexará el</Accounts>
etiqueta de cierre.El código de análisis se parece a esto:
La
Statements
clase solo lee en el<StatementsAvailable>
nodoLa
Statement
clase se vería muy parecidafuente
Para los subobjetos,
ReadSubtree()
le brinda un lector xml limitado a los subobjetos, pero realmente creo que lo está haciendo de la manera difícil. A menos que tenga requisitos muy específicos para manejar xml inusual / impredecible, useXmlSerializer
(quizás junto consgen.exe
si realmente lo desea).XmlReader
es ... complicado. Contraste con:fuente
El siguiente ejemplo navega por la ruta para determinar el tipo de nodo actual y luego usa XmlWriter para generar el contenido de XmlReader.
El siguiente ejemplo usa los métodos XmlReader para leer el contenido de elementos y atributos.
fuente
Puede recorrer xmlnode y obtener los datos ... Lector XML de C #
fuente
No tengo experiencia. Pero creo que XmlReader es innecesario. Es muy dificil de usar.
XElement es muy fácil de usar.
Si necesita rendimiento (más rápido), debe cambiar el formato de archivo y usar las clases StreamReader y StreamWriter.
fuente