2009-08-01 12 views
6

Chcę napisać jakiś tekst, który zawiera białe znaki, takie jak newline i tab do pliku XML więc używamJak zachować nowe linie w CDATA podczas generowania XML?

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

ale kiedy czytam to z powrotem w użyciu

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

Otrzymuję ciąg który nie ma już nowych linii.
Kiedy patrzę bezpośrednio na xml na dysku, nowe linie wydają się zachowane. więc problem występuje podczas odczytu w pliku xml.

Jak mogę zachować nowe linie?

Dzięki!

+2

Czy możesz zamieścić bardziej kompletny przykład kodu? – skaffman

+0

to element. Wkrótce dodam więcej kodu. – clamp

+0

kiedy otrzymasz wartość "x", jest to równoważne "somestring" minus newlines? – akf

Odpowiedz

5

I don wiesz, jak analizujesz i piszesz swój dokument, ale oto przykład ulepszonego kodu na podstawie Twojego:

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

Serializacja przy użyciu LSSerializera jest metodą W3C (see here). Wydajność jest zgodna z oczekiwaniami, z separatorami liniowymi:

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

dziękuję, próbowałem, ale to nie działa dla mnie. podczas gdy widzę, że linie podziału znajdują się w xmlfile na dysku, po przeczytaniu ich za pomocą tego kodu, zniknęły. może moja postać w linii prostej jest zła. jak mogę się dowiedzieć, który to jest? – clamp

+0

Wyjście, które pokazałem, jest rzeczywistym wyjściem z mojej własnej maszyny z przykładu kodu, który napisałem. Czy próbowałeś napisać tekst z kodem, który zasugerowałem? Czy tylko po to, żeby przeczytać to za pomocą mojego kodu? Co to jest kodowanie pliku (widać, że w moim przykładzie kodowanie to UTF-16). Miałem podobny problem, ponieważ nie korzystałem z tego samego kodowania i naprawiłem je za pomocą funkcji Charset.forName() z użyciem właściwego kodowania. –

+0

Tak, próbowałem twojego prawdziwego kodu w moim przypadku. Użyłem dokładnie tego samego kodu do wyprowadzenia ciągu. ale nie zawiera białych znaków. kodowanie, którego używam to kodowanie = "ISO-8859-1" Spróbuję użyć UTF-16 – clamp

0

EDIT: wyciąć wszystkie nieistotnych rzeczy

jestem ciekaw, co DOM realizacja używasz, ponieważ nie odzwierciedlają domyślne zachowanie jednego z kilku JVMs Próbowałam (wysyłane z implem Xerces). Interesuje mnie również to, jakie znaki nowej linii mają twój dokument.

Nie jestem pewien, czy CDATA powinien zachować białe spacje. Podejrzewam, że wiąże się to z wieloma czynnikami. Czy DTD/schematy nie wpływają na sposób przetwarzania białych znaków?

Możesz spróbować użyć atrybutu xml: space = "preserve".

+0

Tak, wiem, dlatego używam getFirstchild() – clamp

+0

Uh! Tego nie dostałem! – McDowell

+0

dzięki, gdzie dokładnie powinienem dodać atrybut xml: space = "preserve"? do węzła zawierającego tekst lub do katalogu głównego xml? – clamp

2

Należy sprawdzić typ każdego węzła za pomocą metody node.getNodeType(). Jeśli typ to CDATA_SECTION_NODE, musisz połączyć osłony CDATA z węzłem node.getNodeValue.

+0

Tak, typem węzła jest CDATA. ale co masz na myśli mówiąc o strażnikach CDATA firmy concat? – clamp

2

Nie musisz używać CDATA, aby zachować białe znaki. Kod XML specification określa sposób kodowania tych znaków.

Tak na przykład, jeśli element z wartości, które zawierają nową przestrzeń należy zakodować go z powrotem

&#xA; 

przewozu:

&#xD; 

itd

+0

dziękuję, ale czy istnieje sposób, aby go nie kodować? aby widziałem sformatowany tekst w samym pliku xml? – clamp

0

xml: space = 'preserve' nie jest to. To jest tylko dla węzłów "wszystkie białe znaki". Oznacza to, że jeśli chcesz węzły białe znaki

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

jednak zauważyć, że te węzły są tylko białe znaki spacji.

Starałem się, aby Xerces generował zdarzenia umożliwiające izolację również treści CDATA. Nie mam jeszcze rozwiązania.