Python 中使用 SAX 解析器的标记之间的文本

Text between tag using SAX parser in Python

我想使用 SAX 打印 XML 文件中特定标记之间的文本。

但是,某些文本输出包含空格或换行符。

有没有办法只挑选出实际的字符串?我做错了什么?

请参阅下面的代码摘录和 XML 文档。

(我用 Python 2 和 Python 3 得到相同的效果。)

#!/usr/bin/env python3

import xml.sax

class MyHandler(xml.sax.ContentHandler):

        def startElement(self, name, attrs):
                self.tag = name

        def characters(self, content):
                if self.tag == "artist":
                        print('[%s]' % content)

if __name__=='__main__':
        parser=xml.sax.make_parser()
        Handler=MyHandler()
        parser.setContentHandler(Handler) #overriding default ContextHandler
        parser.parse("songs.xml")
<?xml version="1.0"?>
<genre catalogue="Pop">
  <song title="No Tears Left to Cry">
    <artist>Ariana Grande</artist>
    <year>2018</year>
    <album>Sweetener</album>
  </song>
  <song title="Delicate">
    <artist>Taylor Swift</artist>
    <year>2018</year>
    <album>Reputation</album>
  </song>
  <song title="Mrs. Potato Head">
    <artist>Melanie Martinez</artist>
    <year>2015</year>
    <album>Cry Baby</album>
  </song>
</genre>

如果您想使用 SAX,那么您需要对 XML 规范有扎实的理解。白色 space 的技术名称是 'mixed content'。它出现在第一个子标签之前、子标签之间和最后一个子标签之后。大多数 XML 处理器将报告混合内容的 SAX 事件。有些有一个标志用于抑制它(因为许多应用程序只对纯文本内容或纯元素内容感兴趣)。

解决方案包括:

a) 停止使用 SAX。 DOM 会更直接

b) 添加代码以检测您感兴趣的标签的 startElement 和 endElement 事件。忽略事件,除非您位于 'interesting' 标签之一内。

c) 使用 XSLT 将您的 XML 文档转换为您需要的任何形式(参见 How to transform an XML file using XSLT in Python?

我的选择永远是 c),因为 XSLT 是一种超能力,它使这类任务变得非常简单。

self.tag的值在遇到<artist>开始标签时设置为“艺术家”,直到[=14=调用startElement()时才改变] 开始标签。在这些元素之间是一些无趣的空白,解析器也会针对这些空白报告 SAX 事件。

解决此问题的一种方法是向 MyHandler 添加一个 endElement() 方法,将 self.tag 设置为其他内容。

def endElement(self, name):
    self.tag = "whatever"