2008-10-13 72 views
2

我正在寻找使用Java来解析由远程设备生成的正在进行的事件驱动XML流。这里有两个事件的简化示例:如何解析Java中的“事件XML”?

<?xml version="1.0"?> 
<Event> DeviceEventMsg 
<Param1>SomeParmValue</Param1> 
</Event> 
<?xml version="1.0"?> 
<Event> DeviceEventMsg 
<Param1>SomeParmValue</Param1> 
</Event> 

好像SAX比DOM更适合这个,因为它是一个持续的流,虽然我不熟悉萨克斯。不要对我的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(); 
     } 
    } 
} 
+0

数据流更新有多快? xml头文件之间的连接是否丢失? – simon 2008-10-13 16:52:26

+0

这些事件是家庭自动化设备的开启和关闭事件,所以它们可以分开几秒,但长时间不活动。事件之间保持连接。 – 2008-10-13 17:06:10

回答

1

尝试使用StAX而不是SAX。 StAX允许更多的灵活性,它是流式传输XML的更好解决方案。有几个StAX的实现,我很高兴与codehaus之一,但也有一个从Sun。 它可能会解决你的问题。

+0

你知道一种告诉STAX不要在上面输入的中间输入<?xml version =“1.0”?>的行吗?它再次固定在设备提供的内容上,我无法更改它。 – 2008-10-13 21:19:48

0

如果打印出了名的开始和结束元素的System.out.println(),你会得到这样的:

了startDocument得到的startElement 事件中人物发现 字符得到的startElement参数1 发现字符得到endElement参数1 发现字符得到endElement事件 org.xml.sax.SAXParseException: 处理指令目标匹配 “[xX] [mM] [lL]”是不允许的。 ...

所以我觉得第二

<?xml version="1.0"?>

没有得到一个调用endDocument导致解析器问题。

0

如果添加此:其他捕前

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

你将捕获此特定错误。那么您必须重新打开该设备,或者查看您在文件中可能需要跟踪的静态文件情况。

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

0

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

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

1

多一个建议,特别是关于多个XML声明。是的,这是ILLEGAL xml,所以正确的解析器会使用默认模式对它进行删除。 但一些解析器有替代的“多文档”模式。例如,Woodstox有这个,所以你可以检查出:

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

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

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