2010-02-19 12 views
19

Estoy viendo un comportamiento extraño cuando trato de analizar XML utilizando la clase LINQ XmlReader. Caso de prueba a continuación: parece que si utilizo (XElement)XNode.ReadFrom(xmlReader) o uno de los métodos Read() en XmlReader, pierde los segundos elementos bar en el XML de entrada. Si se agrega espacio en blanco entre </bar> y <bar>, se analizará correctamente el segundo elemento bar.¿Por qué XmlReader omite cualquier otro elemento si no hay un separador de espacios en blanco?

¿Alguien tiene una idea de por qué la corriente de entrada se arruina y cómo evitar este problema?

[Test] 
    [Explicit] 
    public void ShouldParseCorrectNumberOfElements() 
    { 
     var xml = @"<foo><bar>wtf</bar><bar>wtf2</bar></foo>"; 
     XmlReader xmlReader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(xml))); 

     int count = 0; 
     xmlReader.MoveToContent(); 
     while (xmlReader.Read()) 
     { 
      if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "bar") 
      { 
       var element = xmlReader.ReadOuterXml(); 
       Console.WriteLine("just got an " + element); 
       count++; 
      } 
     } 
     Assert.AreEqual(2, count); 
    } 
+0

El bucle se puede optimizar de manera significativa por el uso de 'ReadToFollowing ("barra")' en lugar de 'Read()' (funciona con la respuesta de Jon también). –

+0

Tengo un caso similar y estoy usando 'ReadToFollowing' con' While' y 'ReadOuterXml' dentro del ciclo while. Si el documento está formateado con líneas nuevas, funciona correctamente. Cuando tengo un documento de una sola línea, omite todos los siguientes nodos. –

Respuesta

30

Llamas al ReadOuterXml, que consumirá el elemento y colocará el "cursor" justo antes del siguiente elemento. A continuación, llama al Read, que mueve el cursor (por ejemplo, al nodo de texto dentro del elemento).

Aquí es una alternativa a la hebilla:

while (!xmlReader.EOF) 
{ 
    Console.WriteLine(xmlReader.NodeType); 
    if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "bar") 
    { 
     var element = xmlReader.ReadOuterXml(); 
     Console.WriteLine("just got an " + element); 
     count++;     
    } 
    else 
    { 
     xmlReader.Read(); 
    } 
} 
+0

Oh, ese sentimiento de "uno a uno" ... ¡Gracias de nuevo! –

6

¿Está quizá saltarse una línea llamando a la función de lectura() dentro de la condición del bucle de tiempo y luego la función ReadOuterXml() dentro del bucle en sí?

Cuestiones relacionadas