Как сохранить новые строки в CDATA при генерации XML?
Вопрос
Я хочу написать некоторый текст, содержащий пробелы, такие как newline
и tab
в xml-файл, поэтому я использую
Element element = xmldoc.createElement("TestElement");
element.appendChild(xmldoc.createCDATASection(somestring));
но когда я прочитал это еще раз в using
Node vs = xmldoc.getElementsByTagName("TestElement").item(0);
String x = vs.getFirstChild().getNodeValue();
Я получаю строку, в которой больше нет новых строк.
Когда я смотрю непосредственно в xml на диске, новые строки кажутся сохраненными.таким образом, проблема возникает при чтении в xml-файле.
Как я могу сохранить новые строки?
Спасибо!
Решение
Я не знаю, как вы анализируете и пишете свой документ, но вот улучшенный пример кода, основанный на вашем:
// 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
Другие советы
Вам нужно проверить тип каждого узла с помощью node.getNodeType().Если тип - CDATA_SECTION_NODE, вам нужно объединить защитные элементы CDATA с node.getNodeValue.
Вам не обязательно использовать CDATA для сохранения пробелов.XML -файл спецификация укажите, как кодировать эти символы.
Так, например, если у вас есть элемент со значением, которое содержит новое пространство, вы должны закодировать его с помощью


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

И так далее
Редактировать:отрежьте все неуместные вещи
Мне любопытно узнать, какую реализацию DOM вы используете, потому что она не отражает поведение по умолчанию в паре JVM, которые я пробовал (они поставляются с Xerces impl).Меня также интересует, какие символы новой строки есть в вашем документе.
Я не уверен, что CDATA должен сохранять пробелы - это само собой разумеющееся.Я подозреваю, что здесь замешано много факторов.Разве DTD / schemas не влияют на то, как обрабатываются пробелы?
Вы могли бы попробовать использовать атрибут xml:space="сохранить".
xml:space='сохранить' - это не то.Это только для узлов "со всеми пробелами".То есть, если вы хотите, чтобы пробельные узлы в
<this xml:space='preserve'> <has/>
<whitespace/>
</this>
Но смотрите, что эти пробельные узлы являются ВСЕГО ЛИШЬ пробельными.
Я изо всех сил пытался заставить Xerces генерировать события, позволяющие также изолировать содержимое CDATA.У меня пока нет решения.