Python之sax的ContentHandler类方法处理多行内容的情况

首先贴出一个对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
   #注意这里也有一行空白


 

 

 

 

你可能感兴趣的:(Python之sax的ContentHandler类方法处理多行内容的情况)