7 Stimmen

Wie werden Zeilenumbrüche in CDATA beim Generieren von XML beibehalten?

Ich möchte einen Text schreiben, der Leerzeichen enthält, z. B. newline y tab in eine xml-Datei zu übertragen, also verwende ich

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

aber als ich das damals las, als ich

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

Ich erhalte eine Zeichenfolge, die keine Zeilenumbrüche mehr enthält.
Wenn ich direkt in die Xml-Datei auf der Festplatte schaue, scheinen die Zeilenumbrüche erhalten zu bleiben. Das Problem tritt also beim Einlesen der Xml-Datei auf.

Wie kann ich die Zeilenumbrüche beibehalten?

Gracias.

2 Stimmen

Könnten Sie ein vollständigeres Code-Beispiel veröffentlichen?

0 Stimmen

Es ist ein Element. Ich werde bald mehr Code posten.

0 Stimmen

Wenn Sie den Wert von "x" erhalten, ist er gleichbedeutend mit "somestring" ohne die Zeilenumbrüche?

5voto

Aviad Ben Dov Punkte 6231

Ich weiß nicht, wie Sie Ihr Dokument analysieren und schreiben, aber hier ist ein erweitertes Codebeispiel, das auf Ihrem Dokument basiert:

// 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);                                                                    

Die Serialisierung mit LSSerializer ist der W3C-Weg, um dies zu tun ( siehe hier ). Die Ausgabe ist wie erwartet, mit Zeilentrennzeichen:

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

2voto

fpmurphy Punkte 2383

Sie müssen den Typ jedes Knotens mit node.getNodeType() überprüfen. Wenn der Typ CDATA_SECTION_NODE ist, müssen Sie die CDATA-Guards mit node.getNodeValue verknüpfen.

2voto

LiorH Punkte 17588

Sie müssen nicht unbedingt CDATA verwenden, um Leerzeichen zu erhalten. Die XML Spezifikation angeben, wie diese Zeichen kodiert werden sollen.

Wenn Sie also zum Beispiel ein Element mit einem Wert haben, der ein neues Leerzeichen enthält, sollten Sie es mit

  &#xA;

Kutsche zurück:

 &#xD;

Und so weiter

0voto

McDowell Punkte 105255

EDIT: alles Unwichtige gestrichen

Ich bin neugierig zu wissen, welche DOM-Implementierung Sie verwenden, denn es spiegelt nicht das Standardverhalten der in ein paar JVMs, die ich ausprobiert habe (sie liefern mit einem Xerces-Impl). Ich bin auch daran interessiert, welche Zeilenumbruchzeichen Ihr Dokument hat.

Ich bin mir nicht sicher, ob die Beibehaltung von Whitespace in CDATA eine Selbstverständlichkeit ist. Ich vermute, dass viele Faktoren eine Rolle spielen. Beeinflussen DTDs/Schemata nicht die Verarbeitung von Whitespace?

Sie könnten versuchen, das Attribut xml:space="preserve" zu verwenden.

0voto

Mike Beckerle Punkte 685

Xml:space='preserve' ist es nicht. Das gilt nur für "alle Leerzeichen"-Knoten. Das heißt, wenn Sie die Whitespace-Knoten in

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

Aber achten Sie darauf, dass diese Leerzeichen-Knoten NUR Leerzeichen sind.

Ich habe mich bemüht, Xerces dazu zu bringen, Ereignisse zu erzeugen, die auch die Isolierung von CDATA-Inhalten ermöglichen. Ich habe bisher noch keine Lösung gefunden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X