2

我正在寻找使用 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 ();
        }
    }
}
4

5 回答 5

1

尝试使用StAX而不是 SAX。StAX 提供了更大的灵活性,它是流 XML 的更好解决方案。StAX 的实现很少,我对codehaus的实现非常满意,但也有来自Sun的实现。它可能会解决你的问题。

于 2008-10-13T17:13:29.003 回答
1

还有一个建议,特别是关于多个 xml 声明。是的,这是非法的 xml,因此正确的解析器会使用默认模式来处理它。但是一些解析器有备用的“多文档”模式。例如,伍德斯托克斯有这个,所以你可以查看:

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

基本上,您必须告诉解析器(通过输入工厂)输入是“多个 xml 文档”(ParsingMode.PARSING_MODE_DOCUMENTS)的形式。

如果是这样,它将接受多个 xml 声明,每个声明都表示新文档的开始。

于 2009-02-24T19:12:04.013 回答
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: 处理指令目标匹配“[xX][mM][lL]”是不允许的。...

所以我认为第二个

<?xml version="1.0"?>

没有得到 endDocument 会导致解析器问题。

于 2008-10-13T21:31:10.200 回答
0

如果你添加这个:

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

在另一个捕获之前,您将捕获此特定错误。然后,您必须重新打开设备或对于静态文件情况,您可能需要跟踪您是否在文件中。

或者在结束事件事件时,关闭设备/文件,然后为下一个事件重新打开它。

于 2008-10-13T21:49:22.287 回答
0

RE:Simon 建议捕获 SAXException 以确定您何时到达一个 XML 文档的结尾并到达另一个 XML 文档的开头,我认为这将是一个有问题的方法。如果发生另一个错误(无论出于何种原因),您将无法判断异常是由于错误的 XML 还是由于您已到达文档末尾而引发的。

问题是解析器是用来处理 XML 文档的。不是几个 XML 文档的流。我建议编写一些代码来手动解析传入的数据流,将其分解为包含单个 XML 文档的单个流;然后将这些流串行传递给 XML 解析器(这样可以保证事件的顺序)。

于 2008-10-13T22:12:41.693 回答