Как сохранить новые строки в CDATA при генерации XML? - PullRequest
6 голосов
/ 01 августа 2009

Я хочу написать некоторый текст, содержащий пробельные символы, такие как newline и tab, в файл XML, поэтому я использую

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

но когда я читаю это снова, используя

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

Я получаю строку, в которой больше нет символов новой строки.
Когда я смотрю прямо в XML на диске, новые строки кажутся сохраненными. поэтому проблема возникает при чтении в XML-файле.

Как мне сохранить переводы строки?

Спасибо!

Ответы [ 5 ]

5 голосов
/ 08 августа 2009

Я не знаю, как вы анализируете и пишете свой документ, но вот пример расширенного кода, основанный на вашем:

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

Сериализация с использованием LSSerializer - это способ W3C ( см. Здесь ). Выходные данные, как и ожидалось, с разделителями строк:

--- XML --- 
<?xml version="1.0" encoding="UTF-16"?>
<TestElement><![CDATA[first line
second line ]]></TestElement>
--- Node Text --- 
first line
second line
2 голосов
/ 01 августа 2009

Вам необходимо проверить тип каждого узла, используя node.getNodeType (). Если типом является CDATA_SECTION_NODE, вам необходимо соединить ограждения CDATA с node.getNodeValue.

2 голосов
/ 01 августа 2009

Вам не обязательно использовать CDATA для сохранения пробелов. Спецификация XML определяет способ кодирования этих символов.

Так, например, если у вас есть элемент со значением, которое содержит новый пробел, вы должны закодировать его как

  &#xA;

Возврат каретки:

 &#xD;

и т. Д.

0 голосов
/ 13 декабря 2014

xml: space = 'preserve' не так ли. Это только для узлов "все пробелы". То есть, если вы хотите пустые узлы в

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

Но обратите внимание, что эти пробельные узлы являются ТОЛЬКО пробельными.

Я изо всех сил пытался заставить Xerces генерировать события, позволяющие также изолировать контент CDATA. У меня пока нет решения.

0 голосов
/ 01 августа 2009

РЕДАКТИРОВАТЬ: вырезать все ненужные вещи

Мне любопытно узнать, какую реализацию DOM вы используете, потому что она не отражает поведение по умолчанию того, что было в паре JVM, которые я пробовал (они поставляются с Xerces impl). Мне также интересно, какие символы перевода строки есть в вашем документе.

Я не уверен, должен ли CDATA сохранять пробелы. Я подозреваю, что здесь много факторов. Разве DTD / схемы не влияют на обработку пробелов?

Вы можете попробовать использовать атрибут xml: space = "preserve".

...