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

Разбор очень больших XML-документов (и немного больше) в java

(Все должно быть написано на Java)

Мне нужно создать приложение, которое будет принимать в качестве входных XML-документов, которые, возможно, очень большие. Документ зашифрован - не с XMLsec, а с моим предыдущим алгоритмом шифрования клиента - будет обрабатываться в три этапа:

Сначала поток будет дешифрован в соответствии с вышеупомянутым алгоритмом.

Во-вторых, класс расширения (написанный третьей стороной API, который я предоставляю) будет читать часть файла. Прочитанная сумма не предсказуема - в частности, она не гарантируется в заголовке файла, но может произойти в любой точке XML.

Наконец, еще один класс расширения (то же самое) подразделяет входной XML в подмножество документов 1..n. Возможно, что в какой-то части они частично перекрывают часть документа, обрабатываемого второй операцией, т.е. Я считаю, что мне нужно будет перемотать все механизмы, которые я использую для работы с этим объектом.

Вот мой вопрос:

Есть ли способ сделать это, не заново прочитав всю часть данных в памяти? Очевидно, что я могу реализовать дешифрование как фильтр входного потока, но я не уверен, что можно анализировать XML так, как я описываю; по ходу, так как большая часть документа требуется для сбора информации второго шага, а затем путем перемотки документа и передачи его снова, чтобы разделить его на задания, идеально высвобождая все части документа, которые больше не используются после они прошли.

4b9b3361

Ответ 1

Стакс - это правильный путь. Я бы рекомендовал посмотреть Woodstox

Ответ 2

Это похоже на работу для StAX (JSR 173). StAX - это синтаксический анализатор, который означает, что он работает более или менее как синтаксический анализатор, основанный на событиях, например SAX, но у вас больше контроля над тем, когда прекращать чтение, какие элементы тянуть,...

Юзабилити этого решения будет зависеть от того, что делают ваши классы расширения, если у вас есть контроль над их реализацией и т.д.

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

Реализации StAX можно найти из SUN (SJSXP), Codehaus или несколько других поставщиков.

Ответ 3

Вы можете использовать BufferedInputStream с очень большим размером буфера и использовать mark() до того, как класс расширения будет работать, и reset() после этого.

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

Более общим решением было бы написать собственный BufferedInputStream -workalike, который буферизует диск, если данные, которые должны быть буферизированы, превышают заданный порог.

Ответ 4

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

SAXParserFactory.newInstance().newSAXParser().parse(
  new DecryptingInputStream(), 
  new MyHandler()
);

Ответ 5

Вам может быть интересно XOM:

XOM довольно уникален тем, что он является API с двойным потоком/на основе дерева. Отдельные узлы в дереве могут быть обрабатывается, пока документ по-прежнему в процессе постройки. Включает программы XOM для работы почти так же быстро, как базовый анализатор может предоставлять данные. Вы не нужно ждать, пока документ полностью разбираться, прежде чем вы сможете начните работать с ним.

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

Ответ 6

Посмотрите на библиотеку XOM. Пример, который вы ищете, это StreamingExampleExtractor.java в каталоге образцов исходного дистрибутива. Это показывает способ выполнения потокового анализа большого документа xml только для создания определенных узлов, обработки их и отбрасывания. Он очень похож на саксофонный подход, но имеет гораздо больше возможностей синтаксического анализа, построенных таким образом, что потоковый анализ может быть достигнут довольно легко.

Если вы хотите работать на более высоком уровне, посмотрите NUX. Это обеспечивает высокоточный потоковый xpath API, который считывает только объем данных в памяти, необходимый для оценки xpath.