2010-06-01 10 views
7

hey chicos, Tengo este escenario:Cómo leer de un XmlReader sin moverlo reenvía

while (reader.Read()) 
{ 
    if (reader.NodeType == XmlNodeType.Element && reader.Name == itemElementName) 
    { 
     XElement item = null; 
     try 
     { 
      item = XElement.ReadFrom(reader) as XElement; 
     } 
     catch (XmlException ex) 
     { 
      //log line number and stuff from XmlException class 
     } 
    } 
} 

En el bucle de arriba estoy transformando un determinado nodo (itemElementName) en una XElement.

Algunos nodos serán buenos XML e irán a un elemento XElement; sin embargo, algunos no lo harán.

En el CATCH, me gustaría no solo capturar las cosas estándar de XmlException ... También me gustaría capturar un extracto del Xml actual y una cadena.

Sin embargo, si realizo cualquier tipo de operación de LECTURA en el nodo antes de pasarlo al XElement, mueve el lector hacia adelante.

¿Cómo se puede obtener una "instantánea" de los contenidos del OuterXml del lector sin interferir con su posición?

Respuesta

10

En realidad, ReadSubtree devolverá un lector que "ajusta" el lector original. Entonces, al leer el nuevo, también avanzará el original. Debe considerar XmlReader como un lector de solo reenvío, simplemente no puede volver atrás. En cuanto a su escenario, en lugar de intentar recordar parte del XML, puede solicitar al lector la posición en el archivo de entrada. Simplemente transfiéralo a la interfaz IXmlLineInfo, tiene métodos para devolver la línea y la posición. Usando esto, podría recordar alguna posición inicial (antes del elemento en cuestión) y luego la posición final del error. Y luego lea esa parte del archivo intput como texto sin formato.

+0

sí, perfecto, gracias, eso es exactamente lo que estaba sucediendo. ¡gracias por la explicación! – andy

+0

Ah ... Totalmente malinterpreté el punto de ReadSubTree, entonces ... lo siento.Sin embargo, para ser sincero, esto no es obvio a partir de la documentación en el navegador de objetos, pero la página de MSDN lo hace más claro. – Flynn1179

+1

Acabo de regresar y eché un vistazo al código que tengo que lo usa; en realidad, deja de leer por completo una vez que ha terminado con el subárbol, por lo que nunca me di cuenta de que también había avanzado el lector original. – Flynn1179

3

No utilice ninguna operación de "Lectura" en el lector; como ha descubierto, esto lo hace avanzar. Use llamadas a propiedades como reader.HasValue y reader.Value para inspeccionar los contenidos. Busque 'XmlReader' en el navegador de objetos, hay bastantes propiedades que puede leer.

Editar: No creo que haya una manera sencilla de obtener el XML, posiblemente porque el nodo actual puede no ser un XML válido por sí mismo, como un nodo XmlWhiteSpace, XmlText o incluso un XmlAttribute.

+0

gracias flynn ... por lo que para mis propósitos espero obtener un extracto de xml no válido antes de que se produzca el error al intentar crear el XElement. ¿Estás diciendo que eso es imposible? – andy

+1

Probablemente no imposible; Me estoy pateando a mí mismo por no recordar esto antes, pero si llamas a 'reader.ReadSubtree()', crea un XmlReader completamente nuevo que comienza dondequiera que esté 'reader'; puede leer todo lo que quiera sin afectar su "lector" original. No estoy 100% seguro de cómo usaría esto en su situación, pero parece que probablemente sea el camino a seguir. – Flynn1179

0

Otra idea: lea el XML externo (que avanza el lector), luego cree un nuevo lector a partir de este XML que le permite "regresar" y procesar los elementos del nodo actual.

while (r.ReadToFollowing("ParentNode")) 
{ 
    parentXml = r.ReadOuterXml(); 

    //since ReadOuterXml() advances the reader to the next parent node, create a new reader to read the remaining elements of the current parent 
    XmlReader r2 = XmlReader.Create(new StringReader(parentXml)); 
    r2.ReadToFollowing("ChildNode"); 
    childValue = r2.ReadElementContentAsString(); 
    r2.Close(); 
}     
1

Lo que hice fue leer solo el elemento en un XmlDocument y leerlo en su lugar. En mi caso, tuve que convertir un documento de flujo a HTML. Tuve que leer un elemento interno para asignar un "estilo" al elemento HTML principal.

Cuestiones relacionadas