Как сохранить пробел перед элементом документа при разборе с Java? - PullRequest
7 голосов
/ 15 мая 2009

В моем приложении я изменяю некоторую часть файлов XML, которая начинается следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: version control yadda-yadda $ -->

<myElement>
...

Обратите внимание на пустую строку перед <myElement>. После загрузки, изменения и сохранения результат далеко не радует:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: version control yadda-yadda $ --><myElement>
...

Я обнаружил, что пробел (одна новая строка) между комментарием и узлом документа вообще не представлен в DOM. Следующий автономный код надежно воспроизводит проблему:

String source =
    "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<!-- foo -->\n<empty/>";
byte[] sourceBytes = source.getBytes("UTF-16");

DocumentBuilder builder =
    DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc =
    builder.parse(new ByteInputStream(sourceBytes, sourceBytes.length));

DOMImplementationLS domImplementation =
    (DOMImplementationLS) doc.getImplementation();
LSSerializer lsSerializer = domImplementation.createLSSerializer();
System.out.println(lsSerializer.writeToString(doc));

// output: <?xml version="1.0" encoding="UTF-16"?>\n<!-- foo --><empty/>

У кого-нибудь есть идеи, как этого избежать? По сути, я хочу, чтобы вывод был таким же, как ввод. (Я знаю, что объявление xml будет сгенерировано заново, поскольку оно не является частью DOM, но здесь это не проблема.)

Ответы [ 5 ]

6 голосов
/ 15 мая 2009

У меня была такая же проблема. Моим решением было написать собственный синтаксический анализатор XML: DecentXML

Основная функция: он может на 100% сохранить исходные данные, пробелы, объекты, все. Это не будет беспокоить вас деталями, но если ваш код должен генерировать XML следующим образом:

 <element
     attr="some complex value"
     />

тогда можно.

3 голосов
/ 15 мая 2009

Почему вы хотите этого избежать?

Пустое пространство вне тегов / элементов определяется как незначительное в спецификации. Он просто не существует в том, что касается информационного набора, представленного вашим DOM.

Следовательно, после повторной сериализации DOM его там не будет.

Если вы разрабатываете что-то, что опирается на эту пустую строку ... Не надо.

2 голосов
/ 15 мая 2009

Основная причина заключается в том, что стандарт DOM Level 3 не может представлять текстовые узлы как дочерние элементы документа без нарушения спецификации. Пробелы будут отброшены любым совместимым парсером.

Document -- 
    Element (maximum of one),
    ProcessingInstruction,
    Comment,
    DocumentType (maximum of one)

Если вам требуется совместимое со стандартами решение, а целью является удобочитаемость, а не воспроизведение на 100%, я бы искал его в вашем механизме вывода.

1 голос
/ 15 мая 2009

В целом, пробелы считаются неактуальными в XML и, следовательно, не сохраняются при разборе файла XML. Большинство библиотек, которые выводят XML, имеют возможность выводить его с хорошим форматированием и правильными отступами, но он всегда будет достаточно общим. Нет "есть дополнительная строка справа здесь ".

0 голосов
/ 15 мая 2009

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

В любом случае, если вы все еще хотите, чтобы появилась эта пустая строка, я бы предложил загрузить исходный код используемого вами анализатора XML и изменить его поведение. Но имейте в виду, что это не стандартный XML, и он не будет совместим с другими приложениями.

...