SAX解析器如何处理字符?

6 投票
3 回答
1121 浏览
提问于 2025-04-16 14:10

我写了一段小代码来解析一个XML文件,想要打印出里面的字符,但每个字符似乎会调用characters()这个回调函数三次。

代码:

def characters(self,chrs):
            if self.flag==1:
                    self.outfile.write(chrs+'\n')

XML文件:

<e1>9308</e1>
<e2>865</e2>

而输出的结果像这样,出现了很多空行。


9308


865

我觉得应该是这样的:

9308

865

为什么会有空行呢?我查了一下文档信息:

characters(self, content)

接收字符数据的通知。解析器会调用这个方法来报告每一块字符数据。SAX解析器可能会将所有连续的字符数据作为一块返回,或者将其拆分成几块;但是,任何单个事件中的所有字符都必须来自同一个外部实体,这样定位器才能提供有用的信息。

所以SAX会把一个字符区域处理成几个片段?并且回调好几次?

3 个回答

0

self.outfile.write(chrs+'\n') 这种写法,你根本看不到具体发生了什么。

试试用 self.outfile.write("Chrs: %r\n" % chrs) 这个写法。

可以查一下内置的 repr() 函数…… "%r" % foorepr(foo) 产生的结果是一样的;这两种写法在错误信息和调试的时候都非常有用。

0

所以SAX会把一个字符区域处理成几个小片段吗?然后回调好几次?

在你的情况中,这显然是发生了——你还有什么疑问吗?

不过你描述的问题不太清楚,因为你没有具体说明你在使用哪个解析器。

4

你发的这个XML例子显然不是完整的XML,因为那样的话会出错(而且SAX解析器会告诉你出错,而不是生成你的输出)。所以我假设这个XML还有更多内容没有展示给我们。

你需要知道的是,每一个在XML元素之间的空白字符都是字符数据。所以如果你有这样的内容:

<foo>
  <bar>123</bar>
</foo>

那么你至少有三个文本节点:一个包含 "\n "(也就是一个换行符和两个空格),一个包含 "123",最后还有一个包含 "\n"(也就是仅仅一个换行符)。

撰写回答