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

Есть ли какой-либо процессор XPath для SAX-модели?

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

<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!

Ответ 7

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

Ответ 8

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

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

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

Ответ 9

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

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

Ответ 10

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

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

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

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

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

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

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

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

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

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

Ответ 11

Мм, я не знаю, действительно ли я тебя понимаю. Насколько мне известно, модель SAX ориентирована на события. Это означает, что вы что-то делаете, если во время разбора встречается определенный node. Да, это лучше для памяти, но я не вижу, как вы хотели бы получить XPath. Поскольку SAX не создает модель, я не думаю, что это возможно.

Ответ 12

Стандартный API-интерфейс javax xpath технически уже работает с потоками; javax.xml.xpath.XPathExpression можно оценить с помощью InputSource, который, в свою очередь, можно построить с помощью Reader. Я не думаю, что он создает DOM под обложками.

Ответ 14

Я не думаю, что xpath работает с SAX, но вы можете взглянуть на StAX, который является расширенным потоковым XML-API для Java.

http://en.wikipedia.org/wiki/StAX