【问题标题】:How exactly does SAX parse a document?SAX 究竟是如何解析文档的?
【发布时间】:2011-10-04 23:07:18
【问题描述】:

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

<?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 调用中解析数据时,我将当前元素的名称保存为私有变量。有没有更简单/更好的方法?

【问题讨论】:

    标签: java xml sax


    【解决方案1】:

    是的,你已经掌握了它的要点。

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

    【讨论】:

      【解决方案2】:

      遗憾的是,SAX 状态机没有很好的文档记录。与其告诉你一些细节,我建议你编写你的第一个内容处理程序,它只记录控制台上发生的所有事情,并使用不同的输入进行播放。

      但是...是的,您已经掌握了要点。

      就“最简单的解析方式”而言,我很想说“不是 SAX”。在使用 SAX 时,您需要以一种或另一种方式实现反映文档中结构转换的状态机。如果文档很简单,您甚至可能无法将其识别为状态机本身。但是,如果您这样考虑,我认为随着事件的进行,您将很容易了解如何存储您需要的东西。

      【讨论】:

      • 不幸的是,我很确定我必须使用 SAX,因为我在 Android 上使用 Restlet,除非你知道更好的解决方案。
      猜你喜欢
      • 2012-08-03
      • 2013-01-09
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 2013-05-20
      • 2016-04-08
      • 1970-01-01
      相关资源
      最近更新 更多