Domanda

Voglio scrivere del testo contenente caratteri di spazi bianchi come newline e tab in un file xml, quindi uso

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

ma quando lo rileggo usando

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

Ricevo una stringa che non ha più righe.
Quando guardo direttamente nel file XML su disco, le nuove righe sembrano conservate. quindi il problema si verifica durante la lettura del file xml.

Come posso preservare le nuove righe?

Grazie!

È stato utile?

Soluzione

Non so come analizzare e scrivere il documento, ma ecco un esempio di codice avanzato basato sul tuo:

// 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 serializzazione tramite LSSerializer è il modo W3C per farlo ( vedi qui ). L'output è come previsto, con i separatori di riga:

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

Altri suggerimenti

Devi controllare il tipo di ogni nodo usando node.getNodeType (). Se il tipo è CDATA_SECTION_NODE, devi concatenare le protezioni CDATA a node.getNodeValue.

Non è necessario utilizzare CDATA per conservare i caratteri degli spazi bianchi. Le XML specifica specificano come codificare questi caratteri.

Ad esempio, se hai un elemento con valore che contiene nuovo spazio, dovresti codificarlo con

  &#xA;

Ritorno a capo del carrello:

 &#xD;

E così via

EDIT: taglia tutte le cose irrilevanti

Sono curioso di sapere quale implementazione DOM stai usando, perché non rispecchia il comportamento predefinito di quello in un paio di JVM che ho provato (spedito con un impl Xerces). Sono anche interessato a quali personaggi newline ha il tuo documento.

Non sono sicuro se CDATA debba preservare gli spazi bianchi sia scontato. Ho il sospetto che ci siano molti fattori coinvolti. I DTD / schemi non influenzano il modo in cui gli spazi bianchi vengono elaborati?

Puoi provare a usare xml: space = " preservare " attributo.

xml: space = 'preservare' non è vero. Questo è solo per " tutti gli spazi bianchi " i nodi. Cioè, se vuoi i nodi degli spazi bianchi in

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

Ma vedi che quei nodi di spazi bianchi sono SOLO spazi bianchi.

Ho avuto difficoltà a convincere Xerces a generare eventi che consentissero anche l'isolamento del contenuto CDATA. Non ho ancora una soluzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top