我试图通过简单地实现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
调用中解析数据时。这样做有更简单/更好的方法吗?
答案 0 :(得分:1)
遗憾的是,SAX状态机没有很好的文档记录。而不是告诉你一些细节,我建议你写作你的第一个内容处理程序,它只记录控制台发生的一切,并使用不同的输入。
但是......是的,你已经掌握了它的主旨。
就“最简单的解析方式”而言,我很想说“不是SAX”。在使用SAX时,您需要以某种方式实现反映文档中结构转换的状态机。如果文档很简单,您甚至可能不会将其视为状态机本身。但是如果你这么想的话,我认为很容易看到如何在事件发生时存储你需要的东西。
答案 1 :(得分:1)
是的,你已经掌握了它的主旨。
SAX是一个非常低级的界面,所以不要指望它很容易。在大多数SAX应用程序中,您可能希望维护一个堆栈,其中startElement将元素名称压入堆栈,endElement将其弹出。如果您没有处理混合内容,那么characters()应该附加到与堆栈顶部的元素关联的StringBuffer,并且您应该在endElement事件发生时处理StringBuffer中的字符内容。那是因为角色内容可以分解为对角色()的多次调用,无论解析器想要什么。