如何使用Python SAX解析器获取并存储XML标签之间的文本为字符串?

1 投票
1 回答
1496 浏览
提问于 2025-04-17 17:42

我有一个看起来像这样的XML文件:

<TAG1>
   <TAG2 attribute1 = "attribute_i_need" attribute2 = "attribute_i_dont_need" >
      Text I want to use
   </TAG2>
   <TAG3>
      Text I'm not interested in
   </TAG3>
   <TAG4>
      More text I want to use
   </TAG4>

我需要从中提取出“我想用的文本”和“更多我想用的文本”,但不想要“我不感兴趣的文本”,并且希望这些文本能以字符串的形式返回,以便后面可以用在其他函数中。同时,我还需要获取“我需要的属性”,也希望它能以字符串的形式返回。我之前没用过sax解析器,现在完全不知道该怎么做。我能用以下代码打印出文档中的所有文本:

import xml.sax

class myHandler(xml.sax.ContentHandler):

    def characters(self, content):
        print (content)

parser = xml.sax.make_parser()
parser.setContentHandler(myHandler())
parser.parse(open("sample.xml", "r"))

这段代码基本上会给我这样的输出:

Text I want to use
Text I'm not interested in
More text I want to use

但问题有两个方面。首先,这个输出包含了我不感兴趣的文本。其次,它只是打印文本而已。我不知道怎么只打印特定的文本,或者写出能把文本作为字符串返回的代码,这样我就可以把它赋值给一个变量,后面使用。而且我甚至不知道怎么开始提取我感兴趣的属性。

有没有人知道怎么解决这个问题?我希望能用sax解析器来解决,因为我对它的工作原理至少有一点模糊的了解。

1 个回答

1

这个想法是,在遇到TAG2或TAG4之后,开始保存所有的字符,并在元素结束时停止。一个开始的元素也是检查和保存有趣属性的机会。

import xml.sax

class myHandler(xml.sax.ContentHandler):
    def __init__(self):
        self.text = []
        self.keeping_text = False
        self.attributes = []

    def startElement(self, name, attrs):
        if name.lower() in ('tag2', 'tag4'):
            self.keeping_text = True

        try:
            # must attribute1 be on a tag2 or anywhere?
            attr = attrs.getValue('attribute1')
            self.attributes.append(attr)
        except KeyError:
            pass

    def endElement(self, name):
        self.keeping_text = False

    def characters(self, content):
        if self.keeping_text:
            self.text.append(content)

parser = xml.sax.make_parser()
handler = myHandler()
parser.setContentHandler(handler)
parser.parse(open("sample.xml", "r"))

print handler.text
print handler.attributes

# [u'\n', u'      Text I want to use', u'\n', u'   ',
#  u'\n', u'      More text I want to use', u'\n', u'   ']
# [u'attribute_i_need']

我觉得 BeautifulSoup 或者直接使用 lxml 会更简单。

撰写回答