Я хочу использовать Java для анализа текущего потока XML-данных диска событий, созданного удаленным устройством. Вот упрощенный пример двух событий:
<?xml version = "1.0"?>
<Event> DeviceEventMsg
<Param1>SomeParmValue</Param1>
</Event>
<?xml version = "1.0"?>
<Event> DeviceEventMsg
<Param1>SomeParmValue</Param1>
</Event>
Кажется, что SAX больше подходит для этого, чем DOM, потому что это непрерывный поток, хотя я не так хорошо знаком с Sax. Не кричите на меня из-за структуры XML - я ее уже знаю и не могу ее изменить.
И да, устройство ДЕЙСТВИТЕЛЬНО отправляет директиву xml перед каждым событием. Моя первая проблема в том, что вторая инструкция обработки xml хрипит парсером SAX.
Может ли кто-нибудь предложить способ обойти это?
Код, который я использую до сих пор, который хрипит во второй инструкции обработки xml, таков:
public class TestMe extends HandlerBase {
public void startDocument () throws SAXException
{
System.out.println("got startDocument");
}
public void endDocument () throws SAXException
{
System.out.println("got endDocument");
}
public void startElement (String name, AttributeList attrs) throws SAXException
{
System.out.println("got startElement");
}
public void endElement (String name) throws SAXException
{
System.out.println("got endElement");
}
public void characters (char buf [], int offset, int len) throws SAXException
{
System.out.println("found characters");
}
public void processingInstruction (String target, String data) throws SAXException
{
System.out.println("got processingInstruction");
}
public static void main(String[] args) {
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = factory.newSAXParser();
// using a file as test input for now
saxParser.parse( new File("devmodule.xml"), new TestMe() );
} catch (Throwable err) {
err.printStackTrace ();
}
}
}
События представляют собой события включения и выключения устройства домашней автоматизации, поэтому они могут быть разделены на секунды, но с длительными периодами бездействия. Связь поддерживается между событиями.




Попробуйте использовать StAX вместо SAX. StAX обеспечивает большую гибкость и является лучшим решением для потоковой передачи XML. Реализаций StAX немного, мне очень нравится кодхаус, но есть еще одна от солнце. Это может решить ваши проблемы.
Знаете ли вы, как сказать STAX, чтобы он не прерывал строку <? Xml version = "1.0"?>, Которая находится в середине ввода, который я дал выше? Опять же, это исправлено в том, что предоставляет устройство, и я не могу это изменить.
Если вы распечатаете имя для начального и конечного элементов System.out.println (), вы получите что-то вроде этого:
got startDocument got startElement Event found characters found characters got startElement Param1 found characters got endElement Param1 found characters got endElement Event org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed. ...
Так что думаю второй
<?xml version = "1.0"?>
без получения endDocument вызывает проблему с анализатором.
Если вы добавите это:
catch(SAXException SaxErr){
System.out.println("ignore this error");
}
перед другим уловом вы поймаете именно эту ошибку. затем вам придется повторно открыть устройство или для случая статического файла, который вам, возможно, придется отслеживать, находились ли вы в файле.
Или в конце события события закройте устройство / файл, а затем снова откройте его для следующего события.
RE: Предложение Саймона перехватить SAXException, чтобы определить, когда вы подошли к концу одного XML-документа и достигли начала другого, я думаю, что это будет проблематичный подход. Если произойдет еще одна ошибка (по какой-либо причине), вы не сможете определить, было ли выброшено исключение из-за ошибочного XML или из-за того, что вы достигли конца документа.
Проблема в том, что парсер предназначен для обработки XML-документа; не поток из нескольких XML-документов. Я бы предложил написать код для ручного анализа входящего потока данных, разбив его на отдельные потоки, содержащие один XML-документ; а затем последовательно передать эти потоки синтаксическому анализатору XML (чтобы гарантировать порядок ваших событий).
Нет ли XML-парсеров, которые будут перехватывать серию XML-документов, поступающих через один непрерывный входной поток?
Синтаксические анализаторы XML предназначены для анализа правильно сформированных XML-документов (ну, технически некоторые из них, вероятно, могут обрабатывать фрагменты документов). То, что у вас есть, не является правильно сформированным XML-документом.
@sgreeve, согласен, с моим предложением вам нужно будет каким-то образом проверить эту конкретную ошибку или обработать любую ошибку в конце документа. Ваше предложение хорошее, предварительный анализ (путем поиска известного шаблона) в хорошо сформированный документ или документы перед передачей синтаксическому анализатору xml.
Еще одно предложение, в частности, относительно нескольких объявлений xml. Да, это НЕЗАКОННЫЙ xml, поэтому правильные парсеры будут блокировать его, используя режимы по умолчанию. Но у некоторых парсеров есть альтернативные «многодокументные» режимы. Например, у Woodstox есть это, поэтому вы можете проверить:
http://www.cowtowncoder.com/blog/archives/2008/04/entry_66.html
По сути, вы должны сообщить синтаксическому анализатору (через фабрику ввода), что ввод находится в форме «нескольких XML-документов» (ParsingMode.PARSING_MODE_DOCUMENTS).
Если это так, он будет принимать несколько объявлений xml, каждое из которых указывает начало нового документа.
Как быстро обновляется поток данных? Потеряно ли соединение между заголовками xml?