Как заменить строку в xml-файле без загрузки содержимого файла в память в java?

Мое приложение создает очень большой XML-файл (около 300 тыс. транзакций). Каждая транзакция будет иметь около 20 элементов xml. Таким образом, он создает огромный файл xml. Мы не использовали JAXB, SAX или DOM для создания XML-файла, так как память является ограничением. Теперь мне нужно заменить определенные значения тегов в XML-файле после его создания. Я знаю, что нужно заменить, и значение для замены. Как я могу заменить эти переменные, не загружая весь файл в память? Для 300 тыс. транзакций размер файла составляет около 600 МБ. Поэтому мы не хотим загружать весь файл в память для замены нескольких переменных.

Мы используем Java5. Есть ли способ сделать это?


person Bharat Kondapalli    schedule 30.04.2015    source источник


Ответы (3)


Вы можете попробовать VTD-XML:

  • Эффективный с точки зрения памяти (в 1,3–1,5 раза больше размера XML-документа) синтаксический анализатор XML с произвольным доступом.
  • Самый быстрый синтаксический анализатор XML: на настольном компьютере Core2 2,5 ГГц VTD-XML превосходит синтаксические анализаторы DOM в 5–12 раз, обеспечивая постоянную пропускную способность 150–250 МБ/с на ядро.
  • Парсер XML с возможностью инкрементного обновления, способный вырезать, вставлять, разбивать и собирать XML-документы с максимальной эффективностью.
  • Доступно на C, C++, C# и Java.

Пример изменения XML.

person vzamanillo    schedule 30.04.2015

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

Подробнее об этом процессе — http://docs.oracle.com/javaee/5/tutorial/doc/bnbfl.html#bnbgq

Мне нравится, как Стивен С решает вашу проблему в ответе здесь - Как изменить огромный файл XML с помощью StAX?

person ThisClark    schedule 30.04.2015

Вы можете попробовать потоковое преобразование с помощью XSLT 3.0 (в частности, Saxon-EE).

Я не уверен, что вы подразумеваете под «значениями тегов» (намного проще, если люди используют правильную терминологию...), но если вы имеете в виду значения текстовых узлов, то вы можете написать потоковое преобразование примерно так:

<xsl:mode streamable="yes" on-no-match="shallow-copy"/>

<xsl:template match="xyz/text()[.='old value']">
  <xsl:text>new value</xsl:text>
</xsl:template>

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

person Michael Kay    schedule 30.04.2015
comment
Спасибо, Майкл. не могу поместить это в xsl..тогда как мне это сделать? - person Bharat Kondapalli; 01.05.2015
comment
Всегда можно вызвать код из XSLT в код Java, хотя это не обязательно происходит так часто, как люди себе представляют, потому что логика обычно может быть так же легко написана на XSLT. - person Michael Kay; 03.05.2015