SAX如何解析文档?

3

我正在尝试通过简单实现org.xml.sax.ContentHandler来解析我的一些首个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。是否有更简单/更好的方法?

2个回答

1

很不幸,SAX状态机并没有被很好地记录下来。我建议您首先编写一个将所有发生的事情记录到控制台的内容处理程序,并尝试使用不同的输入。

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

至于“最简单的解析方式”,我倾向于说“不是SAX”。在使用SAX时,您需要以一种反映文档结构转换的状态机实现一种或另一种方式。如果文档很简单,您甚至可能不认为它是状态机。但是,如果您这样考虑,我认为在事件发生时存储所需内容将非常容易。


不幸的是,我相当确定我必须使用SAX,因为我正在使用Restlet在Android上,除非你知道更好的解决方案。 - Naftuli Kay

1

是的,你已经理解了。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接