Pregunta

Quiero escribir un texto que contenga caracteres de espacio en blanco como newline y tab en un archivo xml, así que uso

Element element = xmldoc.createElement("TestElement");
element.appendChild(xmldoc.createCDATASection(somestring));

pero cuando leí esto de nuevo usando

Node vs =  xmldoc.getElementsByTagName("TestElement").item(0);
String x = vs.getFirstChild().getNodeValue();

Me sale una cadena que ya no tiene nuevas líneas.
Cuando miro directamente al xml en el disco, las nuevas líneas parecen conservadas. entonces el problema ocurre cuando se lee en el archivo xml.

¿Cómo puedo preservar las nuevas líneas?

¡Gracias!

¿Fue útil?

Solución

No sé cómo analiza y escribe su documento, pero aquí hay un ejemplo de código mejorado basado en el suyo:

// creating the document in-memory                                                        
Document xmldoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

Element element = xmldoc.createElement("TestElement");                                    
xmldoc.appendChild(element);                                                              
element.appendChild(xmldoc.createCDATASection("first line\nsecond line\n"));              

// serializing the xml to a string                                                        
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();             

DOMImplementationLS impl =                                                                
    (DOMImplementationLS)registry.getDOMImplementation("LS");                             

LSSerializer writer = impl.createLSSerializer();                                          
String str = writer.writeToString(xmldoc);                                                

// printing the xml for verification of whitespace in cdata                               
System.out.println("--- XML ---");                                                        
System.out.println(str);                                                                  

// de-serializing the xml from the string                                                 
final Charset charset = Charset.forName("utf-16");                                        
final ByteArrayInputStream input = new ByteArrayInputStream(str.getBytes(charset));       
Document xmldoc2 = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);

Node vs =  xmldoc2.getElementsByTagName("TestElement").item(0);                           
final Node child = vs.getFirstChild();                                                    
String x = child.getNodeValue();                                                          

// print the value, yay!                                                                  
System.out.println("--- Node Text ---");                                                  
System.out.println(x);                                                                    

La serialización con LSSerializer es la forma W3C de hacerlo ( ver aquí ). El resultado es el esperado, con separadores de línea:

--- XML --- 
<?xml version="1.0" encoding="UTF-16"?>
<TestElement><![CDATA[first line
second line ]]></TestElement>
--- Node Text --- 
first line
second line

Otros consejos

Debe verificar el tipo de cada nodo usando node.getNodeType (). Si el tipo es CDATA_SECTION_NODE, debe concatenar los protectores CDATA a node.getNodeValue.

No necesariamente tiene que usar CDATA para conservar los espacios en blanco. La especificación XML especifica cómo codificar estos caracteres.

Entonces, por ejemplo, si tiene un elemento con valor que contiene nuevo espacio, debe codificarlo con

  &#xA;

Devolución de carro:

 &#xD;

Y así sucesivamente

EDITAR: corta todas las cosas irrelevantes

Tengo curiosidad por saber qué implementación de DOM está utilizando, porque no refleja el comportamiento predeterminado de uno en un par de JVM que he probado (se envían con un Xerces impl). También estoy interesado en los caracteres de nueva línea que tiene su documento.

No estoy seguro de si CDATA debe preservar el espacio en blanco es un hecho. Sospecho que hay muchos factores involucrados. ¿Los DTD / esquemas no afectan la forma en que se procesa el espacio en blanco?

Puede intentar usar el xml: space = " preservar " atributo.

xml: space = 'preservar' no lo es. Eso es solo para " todos los espacios en blanco " nodos Es decir, si desea los nodos de espacios en blanco en

<this xml:space='preserve'> <has/>
<whitespace/>
</this>

Pero observe que esos nodos de espacios en blanco son SOLAMENTE espacios en blanco.

He estado luchando para que Xerces genere eventos que también permitan el aislamiento del contenido CDATA. Todavía no tengo solución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top