Пропуск декларации XML при вызове Transformer с помощью StAXResult - PullRequest
2 голосов
/ 07 марта 2012

Я хотел бы скопировать несколько узлов XML из исходного файла XML в целевой файл.И исходные, и целевые файлы очень большие, поэтому я буду использовать StAX.Обычно файл, который я пытаюсь обработать, выглядит следующим образом:

<root>
  <header>
    <title>A List of persons</title>
  </header>
  <person>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </person>  
  <person>
    <name>John</name>
    <surname>Doe</surname>
  </person>  
  .
  .
  etc...
</root>

Целевые файлы должны иметь следующий формат:

<root>
  <header>
    <title>A List of persons</title>
  </header>
  <person>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </person>
</root>

, где каждый файл должен содержать узел заголовка , ровно один узел person , заключенный в узел root .

Теперь моя проблема заключается в следующем: я пытаюсь прочитать висходный файл через XMLStreamReader и запись его с использованием XMLStreamWriter, оба из которых подключены к экземпляру Transformer, который копирует фрагментов из исходного файла в целевой файл.Преобразователь создается следующим образом:

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

StAXSource stAXSource = new StAXSource(reader);
StAXResult stAXResult = new StAXResult(writer);

У меня также есть специальный метод, который перемещает курсор на нужный фрагмент во входном потоке XML:

// Moves XMLStreamReader cursor to the next fragment. 
moveCursorToNextFragment(XMLStreamReader reader, String fragmentNodeName)

, чтобы вВ итоге я получаю следующее:

// Open file as usual...

// Advance cursor to <header> node, and copy fragment till
// </header> to the output writer. 
moveCursorToNextFragment(reader, "header");
transformer.transform(stAXSource, stAXResult);

// Advance cursor to <person> node, and copy fragment till
// </person> to the output writer.
moveCursorToNextFragment(reader, "person");
transformer.transform(stAXSource, stAXResult);

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

transformer.transform(stAXSource, stAXResult);

Я пытался использовать StreamResult для преобразования вывода следующим образом:

transformer.transform(stAXSource, new StreamResult(myStream));

и объявление XML опущено, но когда я вернулся к использованию StAXResult , объявление XML вернулосьснова.Я также заметил, что OutputKeys.OMIT_XML_DECLARATION не имеет никакого эффекта, независимо от того, включен он или выключен (как и другие параметры, такие как OutputKeys.STANDALONE со значением «yes»).

Короче говоря, кажется, что эти настройки, установленные глобально на Transformer, игнорируются, когда StAXResult является результатом назначения.

Мой вопрос таков: есть ли способ, которым это может быть достигнуто, чтобы Transformer не генерировал объявления XML при каждом вызове Transformer.transform () (т.е. записывал фрагменты без объявления XML)?

Ваша помощь очень ценится и нужна.

1 Ответ

0 голосов
/ 30 марта 2012

Xalan's SAX2StAXStreamWriter делает это.Другая реализация XSLT может вести себя по-другому.Чтобы обойти это, вы можете обернуть писателя и заставить методы startDocument(...) ничего не делать.Библиотека StAXON предоставляет служебный класс StreamWriterDelegate, который помогает сократить необходимый код:

writer = new StreamWriterDelegate(writer) {
  @Override public void writeStartDocument() {}
  @Override public void writeStartDocument(String version) {}
  @Override public void writeStartDocument(String encoding, String version) {}
};

должен помочь.

...