Обновление Там не является никаким готовым синтаксическим анализатором XML в сообществе Java, которое может сделать парсинг XML и NIO. Это является самым близким, я нашел, и это неполно: http://wiki.fasterxml.com/AaltoHome
У меня есть следующий код:
InputStream input = ...;
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLStreamReader streamReader = xmlInputFactory.createXMLStreamReader(input, "UTF-8");
Вопрос, почему делает метод #createXMLStreamReader (), ожидает иметь весь XML-документ во входном потоке? Почему это называют "потоковым читателем", если это, может казаться, не обрабатывает часть данных XML? Например, если я питаюсь:
к нему он сказал бы мне, что я пропускаю закрывающие тэги. Даже, прежде чем я начинаю выполнять итерации самого потокового читателя. Я подозреваю, что просто не знаю, как использовать XMLStreamReader правильно. Я должен смочь предоставить его данные частями, правильно? Мне нужен он, потому что я обрабатываю поток XML, входящий от сетевого сокета, и не хочу загружать целый исходный текст в память.
Спасибо за справку, Yuri.
Какую версию Java вы используете? С JDK 1.6.0_19 я получаю ожидаемое поведение. Итерация по вашему примеру XML-фрагмента дает мне три события:
Четвертый вызов next () вызывает исключение XMLStreamException: ParseError при [row, col]: [2,12] Сообщение: структуры XML-документа должны начинаться и заканчиваться внутри одной и той же сущности.
Посмотрите на эту ссылку, чтобы узнать больше о том, как работают потоковые парсеры и как они сокращают объем памяти. Для входящего XML вам нужно сначала сериализовать входящий XML и создать правильно сформированный XML, а затем передать его потоковому синтаксическому анализатору.
Поток должен содержать контент для всего XML-документа, но не все в памяти одновременно (это то, что делают потоки). Возможно, вы сможете оставить поток и читателя открытыми, чтобы продолжать вводить контент; однако он должен быть частью правильно сформированного XML-документа.
Предложение: вы можете прочитать немного больше о том, как работают сокеты и потоки, прежде чем двигаться дальше.
Надеюсь, это поможет.
Вы можете получить то, что хотите - частичный разбор, но вы не должны закрывать поток, когда вы достигаете конца текущих доступных данных. Держите поток открытым, и парсер будет просто блокироваться, когда дойдет до конца потока. Когда у вас будет больше данных, добавьте их в поток, и синтаксический анализатор продолжит работу.
Такая схема требует двух потоков - один поток выполняет синтаксический анализатор, а другой получает данные. Чтобы соединить эти два потока, используется труба - пара PipeInputStream и PipeOutputStream, которая направляет данные из потока читателя во входной поток, используемый синтаксическим анализатором. (Парсер читает данные из PipeInputStream.)
.