Come preservare le nuove righe in CDATA durante la generazione di XML?
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!
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


Ritorno a capo del carrello:

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.