首先贴出一个对contentHandler类方法的介绍,参考自
http://www.linuxidc.com/Linux/2015-01/111147.htm
- characters(content)方法
- 调用时机
- 从行开始,遇到标签之前,存在字符,content的值为这些字符串。
- 从一个标签,遇到下一个标签之前, 存在字符,content的值为这些字符串。
- 从一个标签,遇到行结束符之前,存在字符,content的值为这些字符串。
- 标签可以是开始标签,也可以是结束标签。
- startDocument()方法:文档启动的时候调用。
- endDocument()方法:解析器到达文档结尾时调用。
- startElement(name, attrs)方法:遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。
- endElement(name)方法:遇到XML结束标签时调用。
问题描述:
对于如下xml文件,文件中有多个<movie>标签,此处只贴出一个作为例子。看到<stars>标签中的内容存在换行的情况,目标是想要输出所有<stars>标签中的完整的内容。
<movie title="Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>
1)abc
2)123
</stars>
<description>A schientific fiction</description>
</movie>
一种非常简单的处理方式是:在characters事件中把当前content到保存到私有变量中,然后在endElement事件中筛选出<stars>标签。当找到目标标签时打印出content的值。因为sax流式处理xml文档,故后面的content会将之前的覆盖,以此保证打印出的content值是所期望的。
# 元素开始事件处理
def startElement(self, tag, attributes):
pass
# 元素结束事件处理
def endElement(self, tag):
if tag == "stars":
print(self.content)
# 内容事件处理
def characters(self, content):
self.content = content
当<stars>标签中的内容无换行时,其内容可以正常获取到。但当它的内容存在换行时,打印出的结果为空。
改进的处理方法是定义一个名为content的变量,在startElement事件中将其赋值为空,每遇到一次</stars>结束标签,就在endElement事件中打印出这个变量的值,最后,最最关键的是在characters事件中对它的值做字符串拼接。
# 元素开始事件处理
def startElement(self, tag, attributes):
self.content = ""
# 元素结束事件处理
def endElement(self, tag):
if tag == 'stars' :
print ('content is : ',self.content)
self.content = ""
# 内容事件处理
def characters(self, content):
self.content += content
这样,遇到<stars>标签将content变量置空,然后characters事件不断把遇到的字符叠加到content变量中,直到遇到</stars>结束标签将其打印出来,并重新置为空。这样得到的结果与期望目标一致,能够把多行内容获取到。这相当于定义了一个buffer, 所有满足条件的字符先存放到buffer中,然后一次性输出。
最后得到的结果是:
content is : #注意这里有换行
1)abc
2)123
#注意这里也有一行空白