Как разобрать «Событие XML» в Java? - PullRequest
2 голосов
/ 13 октября 2008

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

Ответы [ 5 ]

1 голос
/ 24 февраля 2009

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

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

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

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

1 голос
/ 13 октября 2008

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

0 голосов
/ 14 октября 2008

RE: Предложение Саймона перехватить SAXException, чтобы определить, когда вы подошли к концу одного XML-документа и достигли начала другого, я думаю, это будет проблематичным подходом. Если произошла другая ошибка (по какой-либо причине), вы не сможете определить, было ли выброшено исключение из-за ошибочного XML или потому, что вы достигли конца документа.

Проблема в том, что парсер предназначен для обработки XML-документа; не поток нескольких документов XML. Я бы предложил написать некоторый код для ручного анализа входящего потока данных, разбив его на отдельные потоки, содержащие один XML-документ; а затем передать эти потоки в анализатор XML в последовательном порядке (таким образом, гарантируя порядок ваших событий).

0 голосов
/ 14 октября 2008

Если вы добавите это:

catch(SAXException SaxErr){
        System.out.println("ignore this error");
    }

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

Или в конце события события закройте устройство / файл, а затем снова откройте его для следующего события.

0 голосов
/ 14 октября 2008

Если вы напечатаете имя для начального и конечного элемента System.out.println (), вы получите что-то вроде этого:

получил стартДокумент получил стартЭлемент Событие найдено символов найдено символы получили начало Элемент Param1 найденные персонажи получили endElement Param1 найденные персонажи получили endElement Event org.xml.sax.SAXParseException: совпадение целей инструкции обработки «[xX] [mM] [lL]» не допускается. ...

Так что я думаю второй

<?xml version="1.0"?>

без получения endDocument вызывает проблему с анализатором.

...