Подтвердить что ты не робот

Каков наиболее эффективный потоковый XSLT-процессор на основе Java?

У меня есть очень большой XML файл, который мне нужно преобразовать в другой XML файл, и я хотел бы сделать это с помощью XSLT. Меня больше интересует оптимизация памяти, а не оптимизация скорости (хотя скорость тоже будет хорошей!).

Какой Java-процессор XSLT вы бы рекомендовали для этой задачи?

Вы порекомендовали бы любой другой способ сделать это (не-XSLT?, не-Java?), и если да, то почему?

XML файлы в вопросах очень большие, но не очень глубокие - с миллионами строк (элементов), но только около трех уровней.

4b9b3361

Ответ 1

В настоящее время известны только 3 XSLT 2.0 и из них Saxon 9.x, вероятно, наиболее эффективен (по крайней мере, по моему опыту) как по скорости, так и по использованию памяти. Saxon-SA (версия Saxon, не имеющая бесплатной версии в качестве базовой версии B) имеет специальную расширения для потоковой обработки.

Из различных существующих XSLT 1.0,.NET XslCompiledTransform (на С#, а не Java!), кажется, чемпион.

В Java-мире процессоров XSLT 1.0 Saxon 6.x снова очень хорошо.

UPDATE

Теперь, спустя более 3 лет с даты ответа на этот вопрос, нет никаких доказательств того, что разница в эффективности между упомянутыми процессорами XSLT изменилась.

Что касается потоковой передачи:

  • XML-документ с "миллионами узлов" может быть обработан даже без потоковой передачи. Я провел эксперимент, в котором Saxom 9.1.07 обработал XML-документ, содержащий около миллиона элементов 3-го уровня с целыми значениями. Преобразование просто вычисляет их сумму. Общее время преобразования на моем компьютере составляет менее 1,5 секунд. Используемая память составляла 500 МБ - то, что ПК могли иметь даже 10 лет назад,

Вот саксонские информационные сообщения, которые показывают подробности о преобразовании:

Saxon 9.1.0.7J from Saxonica
Java version 1.6.0_17
Stylesheet compilation time: 190 milliseconds
Processing file:/C:\temp\delete\MRowst.xml
Building tree for file:/C:\temp\delete\MRowst.xml using class net.sf.saxon.tinytree.TinyBuilder
Tree built in 1053 milliseconds
Tree size: 3075004 nodes, 1800000 characters, 0 attributes
Loading net.sf.saxon.event.MessageEmitter
Execution time: 1448 milliseconds
Memory used: 506661648
NamePool contents: 14 entries in 14 chains. 6 prefixes, 6 URIs
  1. Saxon 9.4 имеет a функция расширения saxon: stream(), которая может быть используется для обработки огромных XML-документов.

Вот выдержка из документации:

В саксоне есть два способа создания потоковой передачи:

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

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

В варианте этого метода используется новый XSLT 3.0 xsl: iterate инструкции для итерации по записям вместо xsl: for-each. Это позволяет поддерживать рабочие данные, поскольку записи обрабатывается: это позволяет, например, выводить итоговые значения или средние значения в конце прогона или сделать обработку одного запись зависит от того, что было до него в файле. Xsl: итерация инструкция также позволяет ранний выход из цикла, что делает его возможно преобразование для обработки данных с начала большой файл без фактического чтения всего файла.

Поток потоковой передачи доступен как в XSLT, так и в XQuery, но там не является эквивалентом в XQuery для конструкции xsl: iterate.

Потоковые шаблоны: этот подход следует традиционному XSLT процесс обработки рекурсивного спуска входного XML иерархии, сопоставляя правила шаблона с узлами на каждом уровне, но делает это по одному элементу за раз, не создавая дерево в памяти.

Каждый шаблон относится к режиму (возможно, по умолчанию, неназванный режим), и потоковая передача является свойством режима, который может быть указан с использованием новое объявление режима xsl: mode. Если объявлен режим потоковое, то каждое правило шаблона в этом режиме должно подчиняться правила для потоковой обработки.

Правила для того, что разрешено в потоковой обработке, вполне но основной принцип заключается в том, что правило шаблона для данный node может читать только потомки этого node один раз, в заказ. Существуют дополнительные правила, налагаемые ограничениями в текущем Saxon: например, хотя группировка с использованием  теоретически с потоковой реализацией, в настоящее время он не реализован в Saxon.

  1. XSLT 3.0 будет иметь стандартную функцию потоковой передачи. Однако документ W3C по-прежнему имеет статус "рабочий проект", а спецификация потоковой передачи, вероятно, будет изменяться в последующих версиях проекта. В связи с этим не существует реализаций текущей спецификации (потоковой передачи).

  2. Предупреждение. Не все преобразования могут выполняться в потоковом режиме - независимо от XSLT-процессора. Одним из примеров преобразования, которое невозможно выполнить в потоковом режиме (с ограниченным объемом ОЗУ) для огромных документов, является сортировка их элементов (скажем, общим атрибутом).

Ответ 2

Вы можете рассмотреть STX, реализация Java которого Joost. Поскольку он похож на XSLT, но является потоковым процессором, он способен обрабатывать огромные файлы, используя очень мало оперативной памяти.

Joost может использоваться как стандартный javax.xml.transform.TransformerFactory