XMLStreamReader и реальный поток - PullRequest
6 голосов
/ 16 апреля 2010

Обновление В сообществе Java нет готового анализатора XML, который мог бы выполнять анализ NIO и XML. Это самое близкое, что я нашел, и оно неполное: http://wiki.fasterxml.com/AaltoHome

У меня есть следующий код:

* +1007 *

Вопрос в том, почему метод #createXMLStreamReader () ожидает наличия целого XML-документа во входном потоке? Почему он называется «потоковым считывателем», если он не может обрабатывать часть данных XML? Например, если я кормлю:

<root>
    <child>

, это скажет мне, что я пропускаю закрывающие теги. Еще до того, как я начну итерацию самого считывателя потоков. Я подозреваю, что я просто не знаю, как правильно использовать XMLStreamReader. Я должен быть в состоянии снабдить его данными по частям, верно? Мне это нужно, потому что я обрабатываю поток XML, поступающий из сетевого сокета, и не хочу загружать весь исходный текст в память.

Спасибо за помощь, Юрий.

Ответы [ 6 ]

2 голосов
/ 31 мая 2010

Вы можете получить то, что вы хотите - частичный анализ, но вы не должны закрывать поток, когда достигнете конца текущих доступных данных. Держите поток открытым, и синтаксический анализатор просто заблокируется, когда он достигнет конца потока. Когда у вас будет больше данных, добавьте их в поток, и анализатор продолжит работу.

Для этой схемы требуются два потока: один поток выполняет синтаксический анализатор, а другой - выборку данных. Чтобы соединить два потока, вы используете канал - пара PipeInputStream и PipeOutputStream, который помещает данные из потока считывателя во входной поток, используемый синтаксическим анализатором. (Парсер читает данные из PipeInputStream.)

1 голос
/ 02 октября 2010

Если вам абсолютно необходим NIO с контентом «push», есть разработчики, заинтересованные в завершении API для Aalto.Сам Parser является полной реализацией Stax, а также альтернативным «push input» (подача ввода вместо использования InputStream).Таким образом, вы можете вместо этого проверить списки рассылки, если вы заинтересованы.Не все читают вопросы StackOverflow.: -)

1 голос
/ 16 апреля 2010

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

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

Надеюсьэто помогает.

0 голосов
/ 13 марта 2019

С XMLEventReader, использующим анализатор stax, он работает для меня без проблем.

  final XMLEventReader xmlEventReader= XMLInputFactory
                    .newInstance().createXMLEventReader(new FileInputStream(file));

Файл, очевидно, является вашим вводом.

 while(xmlEventReader.hasNext()){

        XMLEvent xmlEvent = xmlEventReader.nextEvent();
        logger.debug("LOG XML EVENT "+xmlEvent.toString());
        if (xmlEvent.isStartElement()){ 
         //continue implementation
0 голосов
/ 16 апреля 2010

Какую версию Java вы используете? С JDK 1.6.0_19 я получаю поведение, которое вы ожидаете. Итерирование вашего примера XML-фрагмента дает мне три события:

  • START_ELEMENT (root)
  • ПЕРСОНАЖИ (пробел между и)
  • START_ELEMENT (ребенок)

Четвертый вызов next () вызывает исключение XMLStreamException: ParseError в [row, col]: [2,12] Сообщение: структуры документа XML должны начинаться и заканчиваться в одной и той же сущности.

0 голосов
/ 16 апреля 2010

Просмотрите эту ссылку, чтобы узнать больше о том, как работают потоковые парсеры и как они уменьшают объем памяти. Для входящего XML необходимо сначала сериализовать входящий XML и создать правильно сформированный XML, а затем передать его потоковому анализатору.

http://www.devx.com/xml/Article/34037/1954

...