2009-05-15 22 views
7

En mi solicitud, alterar una parte de los archivos XML, que comienzan así:¿Cómo mantener el espacio en blanco antes del elemento del documento al analizar con Java?

<?xml version="1.0" encoding="UTF-8"?> 
<!-- $Id: version control yadda-yadda $ --> 

<myElement> 
... 

Nota de la línea en blanco antes <myElement>. Después de cargar, la alteración y el ahorro, el resultado está lejos de ser agradable:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- $Id: version control yadda-yadda $ --><myElement> 
... 

descubrí que el espacio en blanco (una nueva línea) entre el comentario y el nodo de documento no está representado en el DOM en absoluto. El siguiente código autónomo reproduce el problema de manera confiable:

String source = 
    "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<!-- foo -->\n<empty/>"; 
byte[] sourceBytes = source.getBytes("UTF-16"); 

DocumentBuilder builder = 
    DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
Document doc = 
    builder.parse(new ByteInputStream(sourceBytes, sourceBytes.length)); 

DOMImplementationLS domImplementation = 
    (DOMImplementationLS) doc.getImplementation(); 
LSSerializer lsSerializer = domImplementation.createLSSerializer(); 
System.out.println(lsSerializer.writeToString(doc)); 

// output: <?xml version="1.0" encoding="UTF-16"?>\n<!-- foo --><empty/> 

¿Alguien tiene una idea de cómo evitar esto? Básicamente, quiero que la salida sea la misma que la entrada. (Sé que la declaración xml se regenerará porque no forma parte del DOM, pero eso no es un problema aquí).

+1

Terminé pirateando esto en la salida usando una clase OutputStream personalizada que busca la primera aparición de "-><" y agrega dos nuevas líneas; Solo uso esta secuencia si el primer nodo secundario de documento es, de hecho, un comentario. Todavía un truco, pero al menos perfectamente encapsulado :-) –

+0

Tengo el mismo problema. ¿Podría ayudarme? http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodes-count – user3930361

Respuesta

2

La raíz del problema es que la norma DOM Level 3 no puede representar los nodos de texto como hijo de un documento sin romper la especificación. El espacio en blanco se eliminará por cualquier analizador compatible.

Document -- 
    Element (maximum of one), 
    ProcessingInstruction, 
    Comment, 
    DocumentType (maximum of one) 

Si necesita una solución compatible con los estándares y el objetivo es mejorar la legibilidad en lugar de 100% la reproducción, buscaría en su mecanismo de salida.

+0

Buena respuesta, pero este es un error estúpido en la especificación en mi opinión. Ciertamente puede dar salida al texto antes del elemento del documento, pero no puede ingresarlo? – Archie

+0

@McDowell, cualquier cosa que podamos hacer para evitar esto, por favor vea mi pregunta. http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodescount – user3930361

1

En general, los espacios en blanco se consideran irrelevantes en XML y, por lo tanto, no se conservan cuando se analiza un archivo XML . La mayoría de las bibliotecas que generan XML tienen una opción para producirlo con un buen formato y las sangrías correctas, pero siempre será bastante genérico. No "tiene una línea adicional a la derecha aquí".

+1

El punto es que * había * una línea en la entrada original, y debería mantenerse, como es el caso de todos los espacios en blanco en el resto del documento! –

3

¿Por qué quieres evitar esto?

El espacio en blanco fuera de las etiquetas/elementos se define como insignificante por la especificación. Simplemente no existe, en lo que respecta al infoset, que está representado por su DOM.

En consecuencia, al serializar el DOM nuevamente, no estará allí.

Si está en proceso de desarrollar algo que dependa de esta línea en blanco ... No lo haga.

+0

Ningún programa se basa en este formato, por supuesto. Sin embargo, los archivos contienen datos de traducción; están registrados en el control de versiones y se mantienen continuamente. Por lo tanto, sería bueno para ver diferencias si los únicos cambios que mi aplicación hace son intencionales. –

+0

Creo que sí ... Creo que la única manera sensata de tratar con eso es no tener esta línea vacía en los archivos para empezar. No creo que haya ningún método recomendable para mantener esta línea. Tal vez los archivos deberían pasar como regla a través de una herramienta de limpieza antes de registrarse para evitar estas incoherencias. – Tomalak

+0

@Tomalak :: ¿Me pueden ayudar: http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodes-count – user3930361

6

Tuve el mismo problema. Mi solución fue escribir mi propio analizador XML: DecentXML

Característica principal: puede conservar al 100% la entrada original, el espacio en blanco, las entidades, todo. No le molestará con los detalles, pero si su código necesita generar XML como este:

<element 
    attr="some complex value" 
    /> 

entonces usted puede.

+0

Gracias por la sugerencia; ¡DecentXML ciertamente parece algo bueno a tener en cuenta! * bookmarksIt * Es bueno ver que al menos uno de los proyectos "todavía otro analizador" tiene una muy buena razón para existir. Sin embargo, para mi problema actual, preferiría quedarme con la API DOM estándar en todo mi código de procesamiento, y simplemente agregar la línea en la etapa de salida. –

+0

Luego necesita agregar los nodos de texto manualmente antes del elemento raíz. Mire el objeto Documento cómo agregar nodos normales (sin elementos). Si eso no es posible, debe crear un filtro para la secuencia de escritura/salida que piratea la nueva línea allí. –

+0

@AaronDigulla :: ¿Me pueden ayudar en este http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodes-count – user3930361

0

Estoy de acuerdo con Kris y Tomalak, la línea en blanco no es relevante desde el punto de vista XML. Si su aplicación necesita producir una línea en blanco en el resultado, le sugiero que revise la necesidad de ese requisito.

De todos modos, si aún desea que aparezca esa línea en blanco, le sugiero que descargue el código fuente del analizador XML que está utilizando y modifique ese comportamiento. Pero tenga en cuenta que esto no es XML estándar y que no será compatible con otras aplicaciones.

+1

¿Qué pasa con los archivos XML que están destinados a ser editados por seres humanos? En ese caso, el formato original es importante. XML no es solo para la serialización; si fuera así, un formato binario sería mejor. – MarioVilas

Cuestiones relacionadas