Java XML: сохранение копии частичного дерева XML при разборе из сокета - PullRequest
0 голосов
/ 29 марта 2012

У меня есть сокет подачи в синтаксический анализатор, отформатированный как поток ISO 8859/1.Время от времени встречается недопустимый символ, и я получаю исключение SAXParseException со строкой и столбцом, где это произошло, поэтому мне нужно посмотреть, какие данные находятся в этой точке (или, что более важно, зарегистрировать их).

Первоначальностроки, которые обрабатывали данные, были:

InputSource is = new InputSource(new InputStreamReader(socket.getInputStream(), "ISO8859_1"));
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(new ResponseParseHandler(etc, id));
reader.parse(is);

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

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

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

Есть ли что-то действительно простое, что я здесь упускаю?

Ответы [ 2 ]

1 голос
/ 29 марта 2012

Вы можете предоставить свой собственный пользовательский имплик InputStreamReader, который хранит ссылку на нужный вам контент (например, MyInputStreamReader) и предоставляет методы, позволяющие вам получить декодированный контент или последние 1024 байта декодированного контента (или некоторый ограниченный объем).

Пусть существующий элемент InputStreamReader делает то, что он уже делает, просто оберните его некоторой дополнительной логикой в ​​пользовательском классе, а затем передайте ее для создания InputSource.

1 голос
/ 29 марта 2012

В прошлый раз, когда у меня была проблема, подобная этой, я решил ее с помощью SplittingWriter. Это был класс стиля декоратора около двух других Writer с, и когда что-то "записывалось" в SplittingWriter, оно просто делегировало вызов записи обоим своим двум базовым Writer с.

В вашем случае вам нужно что-то вроде SplittingInputStreamReader, которое будет реализовывать InputStreamReader и которое вы передадите в InputSource вместо InputStreamReader, который вы используете в данный момент.

В своем конструкторе SplittingInputStreamReader будет принимать ваш текущий InputStreamReader и некоторый другой объект, давайте назовем его Foo. Реализация методов read в SplittingInputStreamReader тогда делегировала бы вызовы чтения базовому InputStreamReader, переместила бы результаты этих вызовов в Foo, а затем вернула бы результат этих вызовов обратно объекту, который вызвал Это. Таким образом, ваша реализация метода int read() будет выглядеть примерно так:


   @Override
   public int read() {
       int r = this.inputStreamReader.read();
       this.foo.submit(r);
       return r;
   }

Таким образом, когда вы читаете через SplittingInputStreamReader, вы также пишете в Foo, что позволяет вам увидеть, где остановилась запись, если вы дали Foo приличный интерфейс. В конце концов, после реализации SplittingInputStreamReader и Foo ваш код будет выглядеть примерно так:


Foo streamCapture = new Foo();
SplittingInputStreamReader streamReader = new SplittingInputStreamReader(
   new InputStreamReader(socket.getInputStream(), "ISO8859_1"), streamCapture);
InputSource is = new InputSource(streamReader);
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(new ResponseParseHandler(etc, id));
reader.parse(is);
// After parse, if there was an error, check what is in Foo streamCapture

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...