Использование SAX (Java) для анализа нескольких сообщений XML из одного TCP-потока - PullRequest
6 голосов
/ 21 июля 2010

Я нахожусь в положении, когда я использую Java для соединения с портом TCP, и у меня потоковые XML-документы один за другим, каждый из которых ограничен тегом начала <?xml документа.Пример, который демонстрирует формат:

<?xml version="1.0"?>
<person>
    <name>Fred Bloggs</name>
</person>
<?xml version="1.0"?>
<person>
    <name>Peter Jones</name>
</person>

Я использую API org.xml.sax.*.Синтаксический анализ SAX отлично работает для первого документа, но создает исключение, когда он встречается в начале второго документа:

Exception in thread "main" org.xml.sax.SAXParseException: The processing instruction 
target matching "[xX][mM][lL]" is not allowed.

Следующий класс скелета демонстрирует используемую мной установку:

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.FileReader;

public class XMLTest extends DefaultHandler {

  public XMLTest() {
     super();
  }

  public static void main(String[] args) throws Exception {
    XMLReader xr = XMLReaderFactory.createXMLReader();

    XMLTest handler = new XMLTest();
    xr.setContentHandler(handler);
    xr.setErrorHandler(handler);

    xr.parse(new InputSource(new Socket("127.0.0.1", 4555).getInputStream()));
  }
}

У меня нет контроля над форматом xml (это фид финансовых данных), но мне нужно иметь возможность эффективно его анализировать и анализировать все документы.Я провел день / вечер, пробуя разные вещи, но ни один из них не дал результатов.Любая помощь будет принята с благодарностью.

1 Ответ

6 голосов
/ 21 июля 2010

Вы хотите разделить поток на каждый <?xml version="1.0"?> и проанализировать их все по отдельности.BufferedReader может быть полезным в этом.Пример запуска:

reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
StringBuilder builder = null;
for (String line; (line = reader.readLine()) != null;) {
    if (line.startsWith("<?xml")) {
        if (builder != null) {
            xr.parse(new InputSource(builder.toString()));
        }
        builder = new StringBuilder();
    }
    builder.append(line);
}
...