2011-07-14 71 views
3

我试图通过简单地实现org.xml.sax.ContentHandler来解析SAX中的一些第一个XML文档,我不知道我是否理解流程。对于给定的XML文档:SAX如何解析文档?

<?xml version="1.0"?> 
<list> 
    <item> 
     <name>One</name> 
     <description>The number 1, expressed in letters. 
    </item> 
    <item> 
     <name>Two</name> 
     <description>The number 2, expressed in letters. 
    </item> 
</list> 

什么是在解析器事件所期待的顺序?我是否正确地承担以下事项:

startDocument() 
    startElement() -> "list" 

     startElement() -> "item" 
      startElement() -> "name" 
       characters() (>=1 times) -> "One" 
      endElement() -> "name" 
      startElement() -> "description" 
       characters() (>=1 times) -> "The number 1, expressed in letters." 
      endElement() -> "description" 
     endElement() -> "item" 

     startElement() -> "item" 
      startElement() -> "name" 
       characters() (>=1 times) -> "Two" 
      endElement() -> "name" 
      startElement() -> "description" 
       characters() (>=1 times) -> "The number 2, expressed in letters." 
      endElement() -> "description" 
     endElement() -> "item" 

    endElement() -> "list" 
endDocument() 

这就是它的要点吗?

另外,什么是最简单的方法来解析?目前,在每次调用startElement时,我将保存为一个私有变量作为当我在characters调用中解析数据时的当前元素的名称。有没有更容易/更好的方法呢?

回答

1

是的,你有它的要义。

SAX是一个非常低级的界面,所以不要指望它很容易。在大多数SAX应用程序中,您可能需要维护堆栈,其中startElement将元素名称压入堆栈,endElement将其弹出。如果你没有处理混合内容,那么characters()应该附加到与堆栈顶部元素相关联的StringBuffer,并且当endElement事件发生时,你应该处理StringBuffer中的字符内容。这是因为字符内容可以分解为字符()的多个调用,解析器需要的任何方式都可以。

1

不幸的是,SAX状态机没有很好的记录。我并不建议你告诉你一些细节,而是建议你编写第一个内容处理程序,它只记录控制台发生的所有事情,并用不同的输入进行操作。

但是...是的,你已经掌握了它的要点。至于“最简单的解析方式”,我很想说“不是SAX”。在使用SAX时,无论如何,您需要实现一个反映文档结构转换的状态机。如果文档很简单,那么您甚至可能不会将其视为状态机本身。但是如果你这么想,那么我认为在事件发生时如何储存你所需要的东西将是相当容易的。

+0

不幸的是,我很确定我会使用SAX,因为我在使用Restlet的Android上,除非您知道更好的解决方案。 –

+0

您是否尝试过使用[xstream](http://xstream.codehaus.org/faq.htm) – bbaja42