2009-08-01 27 views
6

Tôi muốn viết một số văn bản có chứa ký tự khoảng trắng như newlinetab vào một tập tin xml vì vậy tôi sử dụngLàm thế nào để bảo toàn dòng mới trong CDATA khi tạo XML?

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

nhưng khi tôi đọc lại này trong việc sử dụng

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

tôi nhận được một chuỗi không còn dòng mới nữa.
Khi tôi nhìn trực tiếp vào xml trên đĩa, các dòng mới dường như được giữ nguyên. do đó, vấn đề xảy ra khi đọc trong tệp xml.

Làm cách nào để giữ lại dòng mới?

Cảm ơn!

+2

Bạn có thể đăng một ví dụ mã hoàn chỉnh hơn không? – skaffman

+0

nó là một phần tử. tôi sẽ sớm đăng thêm mã. – clamp

+0

khi bạn nhận được giá trị của 'x', nó tương đương với 'somestring' trừ các dòng mới? – akf

Trả lời

5

tôi don không biết cách bạn phân tích cú pháp và viết tài liệu của bạn, nhưng đây là ví dụ về mã nâng cao dựa trên tài liệu của bạn:

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

Việc tuần tự hóa bằng LSSerializer là cách W3C để thực hiện (see here). Kết quả như mong đợi, với các dấu tách dòng:

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

cảm ơn bạn, tôi đã thử nhưng nó không hoạt động cho tôi. trong khi tôi có thể thấy các dấu ngắt dòng có trong xmlfile trên đĩa, một khi tôi đọc chúng trở lại với mã này, chúng đã biến mất. có lẽ nhân vật linebreak của tôi là xấu. làm thế nào tôi có thể tìm ra, cái nào? – clamp

+0

Đầu ra tôi đã trình bày là một đầu ra thực sự từ máy của riêng tôi trong ví dụ mã tôi đã đăng. Bạn đã thử viết văn bản bằng mã tôi đề xuất chưa? Hoặc chỉ để đọc nó bằng cách sử dụng mã của tôi? Ngoài ra, mã hóa tệp của bạn là gì (bạn có thể thấy rằng trong ví dụ của tôi, mã hóa là UTF-16). Tôi đã có một vấn đề tương tự bằng cách không sử dụng cùng một mã hóa, và tôi đã sửa nó bằng cách sử dụng Charset.forName() với mã hóa thực tế được sử dụng. –

+0

vâng, tôi đã thử mã thực sự của bạn trong trường hợp của tôi. tôi đã sử dụng chính xác cùng một mã để xuất chuỗi. nhưng nó không chứa khoảng trắng. mã hóa tôi sử dụng là mã hóa = "ISO-8859-1" tôi sẽ cố gắng sử dụng UTF-16 – clamp

0

EDIT: cắt tất cả những thứ không liên quan

Tôi tò mò muốn biết những gì DOM thực hiện bạn đang sử dụng, bởi vì nó không bắt chước hành vi mặc định của một trong một vài JVM Tôi đã thử (họ tàu với một Xerces impl). Tôi cũng quan tâm đến những ký tự dòng mới mà tài liệu của bạn có.

Tôi không chắc liệu CDATA có nên giữ khoảng trắng không. Tôi nghi ngờ rằng có nhiều yếu tố liên quan. Các DTD/lược đồ không ảnh hưởng đến cách xử lý khoảng trắng?

Bạn có thể thử sử dụng thuộc tính xml: space = "preserve".

+0

vâng tôi biết, đó là lý do tại sao tôi sử dụng getFirstchild() – clamp

+0

Uh! Bỏ lỡ điều đó! – McDowell

+0

cảm ơn, chính xác tôi nên thêm thuộc tính xml: space = "preserve" vào đâu? tới nút chứa văn bản hoặc gốc xml? – clamp

2

Bạn cần kiểm tra loại mỗi nút bằng cách sử dụng node.getNodeType(). Nếu loại là CDATA_SECTION_NODE, bạn cần phải concat bảo vệ CDATA để node.getNodeValue.

+0

có, loại nút là CDATA. nhưng những gì bạn có nghĩa là với concat CDATA bảo vệ? – clamp

2

Bạn không nhất thiết phải sử dụng CDATA để giữ lại các ký tự khoảng trắng. XML specification chỉ định cách mã hóa các ký tự này.

Vì vậy, ví dụ, nếu bạn có một yếu tố có giá trị có chứa không gian mới, bạn nên mã hóa nó với sự trở lại

&#xA; 

Vận chuyển:

&#xD; 

Và vân vân

+0

cảm ơn, nhưng có cách nào không mã hóa không? sao tôi có thể xem văn bản được định dạng trong tệp xml? – clamp

0

xml: space = 'preserve' phải không. Đó chỉ dành cho các nút "tất cả khoảng trống". Tức là, nếu bạn muốn các nút khoảng trắng trong

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

Nhưng thấy rằng các khoảng trắng đó chỉ là khoảng trắng.

Tôi đã cố gắng để Xerces tạo ra các sự kiện cho phép tách biệt nội dung CDATA. Tôi chưa có giải pháp nào cả.

Các vấn đề liên quan