2009-08-01 13 views
6

Я хочу написать какой-нибудь текст, который содержит пробельные символы, такие как newline и tab в XML-файл, поэтому я используюКак сохранить новые строки в CDATA при создании 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-файле.

Как сохранить символы новой строки?

Спасибо!

+2

Не могли бы вы разместить более полный пример кода? – skaffman

+0

Это Элемент. Я скоро отправлю больше кода. – clamp

+0

, когда вы получаете значение «x», это эквивалентно «somestring» минус символы новой строки? – akf

ответ

5

Я дон Не знаете, как вы разбираете и пишете свой документ, но здесь приведен пример расширенного кода на основе ваших:

// 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 для этого (see here). Выход такой же, как ожидалось, с разделителями линий:

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

спасибо, я пробовал, но это не работает для меня. в то время как я вижу, что в xml-файле на диске появляются строки, как только я прочитал их с помощью этого кода, они исчезли. может быть, мой персонаж-червь плохой. как я могу узнать, какой он? – clamp

+0

Результат, который я показал, является реальным результатом моей собственной машины примера кода, который я опубликовал. Вы пытались написать текст с кодом, который я предложил? Или только прочитать его с помощью моего кода? Кроме того, что такое кодировка вашего файла (вы можете видеть, что в моем примере кодировка UTF-16). У меня была аналогичная проблема, не используя одну и ту же кодировку, и я исправил ее с помощью Charset.forName() с используемой фактической кодировкой. –

+0

yep, я попробовал ваш реальный код в моем случае. Я использовал точно такой же код для вывода строки. но он не содержит пробелов. кодирование, которое я использую, кодирует = «ISO-8859-1», я попытаюсь использовать UTF-16 – clamp

0

EDIT: вырезать все несущественный материал

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

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

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

+0

да, я знаю, поэтому я использую getFirstchild() – clamp

+0

Uh! Пропустил это! – McDowell

+0

спасибо, где именно я должен добавить атрибут xml: space = "сохранить"? к узлу, который содержит текст или корень xml? – clamp

2

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

+0

Да, тип узла - это CDATA. но что вы имеете в виду с конкатентными охранниками CDATA? – clamp

2

Вам не обязательно использовать CDATA для сохранения пробелов. В XML specification указано, как кодировать эти символы.

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

&#xA; 

коляски:

&#xD; 

и так далее

+0

спасибо, но есть ли способ без кодирования? так что я могу видеть форматированный текст в самом файле xml? – clamp

0

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

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

Но видеть, что эти пробельные узлы только пробелы.

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