Есть ли процессор XPath для модели SAX? - PullRequest
55 голосов
/ 08 декабря 2009

Я ищу оценщик XPath, который не перестраивает весь документ DOM, чтобы искать узлы документа: на самом деле целью является управление большим объемом данных XML (в идеале более 2 ГБ) с помощью модели SAX, что очень хорошо для управления памятью и дает возможность поиска узлов.

Спасибо всем за поддержку!

Для всех тех, кто говорит, что это невозможно: я недавно, после того, как задал вопрос, нашел проект с именем "saxpath" (http://www.saxpath.org/),, но я не могу найти ни одного проекта реализации.

Ответы [ 14 ]

15 голосов
/ 07 мая 2013

Мой текущий список (составленный из результатов веб-поиска и других ответов):

Следующим шагом будет использование примеров XMLDog и сравнение производительности всех этих подходов. Затем контрольные примеры следует распространить на поддерживаемые выражения XPath.

11 голосов
/ 07 января 2012

Мы регулярно анализируем сложные файлы XML размером 1 ГБ и более, используя синтаксический анализатор SAX, который извлекает частичные деревья DOM, которые можно удобно запрашивать с помощью XPath. Я писал об этом здесь: http://softwareengineeringcorner.blogspot.com/2012/01/conveniently-processing-large-xml-files.html - источники доступны на github - Лицензия MIT.

9 голосов
/ 31 августа 2011

XPath ДОЛЖЕН работать с SAX, и большинство процессоров XSLT (особенно Saxon и Apache Xalan) поддерживают выполнение выражений XPath внутри XSLT в потоке SAX без создания всего dom.

Им удается сделать это, примерно, следующим образом:

  1. Изучение выражений XPath, которым они должны соответствовать
  2. Получение событий SAX и тестирование, если этот узел нужен или потребуется для одного из выражений XPath.
  3. Игнорирование события SAX, если оно бесполезно для выражений XPath.
  4. Буферизация, если это необходимо

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

То, сколько им удастся оптимизировать, во многом зависит от типа запросов XPath, которые они находят. Как ясно объясняет уже опубликованная саксонская документация, запросы, которые перемещаются «вверх», а затем проходят «горизонтально» (брат или сестра) документа, очевидно, требуют наличия всего документа, но для большинства из них требуется лишь несколько узлов. RAM в любой момент.

Я почти уверен в этом, потому что, когда я все еще делал веб-приложение каждый день, используя Cocoon, у нас возникала проблема с объемом памяти XSLT каждый раз, когда мы использовали выражение "// что-то" внутри XSLT, и довольно часто нам приходилось переработать выражения XPath для лучшей оптимизации SAX.

6 голосов
/ 08 декабря 2009

SAX только для пересылки, в то время как запросы XPath могут перемещаться по документу в любом направлении (рассмотрим оси parent::, ancestor::, preceding:: и preceding-sibling::). Я не понимаю, как это вообще возможно. Наилучшим приближением был бы своего рода ленивый DOM, но в зависимости от ваших запросов это может дать или не дать вам какую-либо выгоду - всегда есть запрос в худшем случае, например //*[. != preceding::*].

4 голосов
/ 22 января 2010

Извините, здесь немного поздний ответ - кажется, что это возможно для подмножества XPath - в общем, это очень сложно из-за того, что XPath может совпасть как вперед, так и назад от "текущей" точки. Мне известны два проекта, которые в некоторой степени решают эту проблему с помощью конечных автоматов: http://spex.sourceforge.net & http://www.cs.umd.edu/projects/xsq. Я не рассматривал их подробно, но похоже, что они используют аналогичный подход.

3 голосов
/ 12 июля 2013

Я добавлю плагин для моего нового проекта под названием AXS. Это в https://code.google.com/p/annotation-xpath-sax/, и идея заключается в том, что вы аннотируете методы с помощью (только для прямой оси) XPath операторы и они вызываются, когда синтаксический анализатор SAX находится на узле, который соответствует ему. Так и с документом

<doc>
<nodes>
  <node name="a">text of node 1</node>
  <node name="b">text of node 2</node>
  <node otherattr="I have attributes!">text of node 3</node>
</nodes>
</doc>

вы можете делать такие вещи, как

@XPath("/nodes/node")
void onNode(String nodeText)
{
  // will be called with "text of node [123]"
}

или

@XPathStart("//node[@name='']")
void onNode3(Attrs node3Attrs) { ... }

или

@XPathEnd("/nodes/node[2]")
void iDontCareAboutNode3() throws SAXExpression
{
  throw new StopParsingExpression();
}

Конечно, библиотека настолько новая, что я еще даже не выпустил ее, но она лицензирована MIT, так что не стесняйтесь попробовать и посмотреть, соответствует ли она вашим потребностям. (Я написал это выполнять очистку экрана HTML с достаточно низкими требованиями к памяти, чтобы я мог запустить его старые устройства Android ...) Если вы найдете ошибки, пожалуйста, дайте мне знать, заполнив их на сайт googlecode!

2 голосов
/ 04 июня 2013

Извините за поздний ответ, но я реализовал простое выражение XPath путь для парсеров SAX. Он поддерживает только тег, атрибут с необязательным значением и индекс из-за прямой природы SAX. Я сделал обработчик делегата для оценки заданного выражения, когда обработчик реализует ExpressionFilter . Хотя эти классы встроены в проект, его не должно быть сложно извлечь.

Дополнительная информация

Примеры - См. Классы с префиксом HandlerHtml

2 голосов
/ 08 декабря 2009

Существуют реализации XPath на основе SAX / StAX, но они поддерживают только небольшое подмножество выражений / осей XPath в основном из-за прямой природы SAX / StAX. Лучшая альтернатива, о которой я знаю, это расширенная VTD-XML , он поддерживает полный xpath, частичную загрузку документов через mem-map ... и максимальный размер документа 256 ГБ, но вам потребуется 64-битная JVM, чтобы использовать его в полной мере

1 голос
/ 08 декабря 2009

Посмотрите на потоковый режим XSLT-процессора Saxon-SA.

http://www.saxonica.com/documentation/sourcedocs/serial.html

"Правила, которые определяют, может ли выражение пути передаваться в потоке:

  • Выражение, которое будет транслироваться, начинается с вызова функции document () или doc ().
  • Выражение пути, введенное вызовом для doc () или документа, должно соответствовать подмножеству XPath, определенному следующим образом:

  • любое выражение XPath приемлемо, если оно соответствует правилам для выражений пути, появляющимся в ограничениях идентичности в XML-схеме. Эти правила не допускают предикатов; первый шаг (но только первый) можно ввести с помощью "//"; последний шаг может при желании использовать атрибут оси; все остальные шаги должны быть простыми шагами оси с использованием дочерней оси.

  • Кроме того, Saxon позволяет выражению содержать объединение, например, doc () / (* / ABC | / XYZ). Союзы также могут быть выражены в сокращенной форме, например, вышеприведенное можно записать как doc () / / (ABC | XYZ).
  • Выражение должно либо выбирать только элементы, либо только атрибуты, либо смесь элементов и атрибутов.

  • Также поддерживаются простые фильтры (один или несколько). Каждый фильтр может применяться к последнему шагу или к выражению в целом, и он должен использовать только нисходящий выбор из узла контекста (оси self, child, attribute, потомок, потомок-или-self или пространства имен). Он не должен быть позиционным (то есть он не должен ссылаться на position () или last () и не должен быть числовым: фактически он должен быть таким, чтобы Saxon мог определить во время компиляции, что он не будет числовым). Фильтры не могут быть применены к союзам или филиалам союзов. Любое нарушение этих условий приводит к тому, что выражение оценивается без оптимизации потоковой передачи.

  • Эти правила применяются после того, как другие выражения оптимизации были применены к выражению. Например, некоторые выражения FLWOR могут быть переписаны в выражение пути, которое удовлетворяет этим правилам.

  • Оптимизация включается только в случае явного запроса, либо с помощью функции расширения saxon: stream (), либо с помощью атрибута saxon: read-Once в инструкции xSLT xsl: copy-of, или в прагме XQuery saxon: поток. Он доступен только в том случае, если таблица стилей или запрос обрабатывается с использованием Saxon-SA. "

Примечание. Скорее всего, в коммерческой версии это средство доступно. Ранее я широко использовал Saxon, и это хорошая работа.

1 голос
/ 08 декабря 2009

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

В результате вы получите (как правило) XML-документ, но вы можете извлечь ожидаемый результат, скажем, из StreamResult, не слишком хлопотно.

...