Как разбирать "XML событий" в Java?

Я хочу использовать 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 ();
        }
    }
}

Как быстро обновляется поток данных? Потеряно ли соединение между заголовками xml?

simon 13.10.2008 20:52

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

Steve Prior 13.10.2008 21:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
2
1 356
5

Ответы 5

Попробуйте использовать StAX вместо SAX. StAX обеспечивает большую гибкость и является лучшим решением для потоковой передачи XML. Реализаций StAX немного, мне очень нравится кодхаус, но есть еще одна от солнце. Это может решить ваши проблемы.

Знаете ли вы, как сказать STAX, чтобы он не прерывал строку <? Xml version = "1.0"?>, Которая находится в середине ввода, который я дал выше? Опять же, это исправлено в том, что предоставляет устройство, и я не могу это изменить.

Steve Prior 14.10.2008 01:19

Если вы распечатаете имя для начального и конечного элементов 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-документов, поступающих через один непрерывный входной поток?

Steve Prior 14.10.2008 06:04

Синтаксические анализаторы XML предназначены для анализа правильно сформированных XML-документов (ну, технически некоторые из них, вероятно, могут обрабатывать фрагменты документов). То, что у вас есть, не является правильно сформированным XML-документом.

ykaganovich 14.10.2008 06:22

@sgreeve, согласен, с моим предложением вам нужно будет каким-то образом проверить эту конкретную ошибку или обработать любую ошибку в конце документа. Ваше предложение хорошее, предварительный анализ (путем поиска известного шаблона) в хорошо сформированный документ или документы перед передачей синтаксическому анализатору xml.

simon 14.10.2008 02:31

Еще одно предложение, в частности, относительно нескольких объявлений xml. Да, это НЕЗАКОННЫЙ xml, поэтому правильные парсеры будут блокировать его, используя режимы по умолчанию. Но у некоторых парсеров есть альтернативные «многодокументные» режимы. Например, у Woodstox есть это, поэтому вы можете проверить:

http://www.cowtowncoder.com/blog/archives/2008/04/entry_66.html

По сути, вы должны сообщить синтаксическому анализатору (через фабрику ввода), что ввод находится в форме «нескольких XML-документов» (ParsingMode.PARSING_MODE_DOCUMENTS).

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

Другие вопросы по теме