我能以某种方式告诉SAX解析器停止某个元素并将其子节点作为字符串吗?

时间:2012-01-05 15:00:56

标签: python xml sax saxparser

我有非常大的XML文档,所以我不想使用DOM,但是在使用SAX解析器解析文档时,我想在某个时刻停止(让我们说当我到达具有某个名称的元素时)并获取所有内容在该元素内部作为字符串。里面的“Everything”不一定是文本节点,它可能包含标签,但我不希望它们被我解析,我只想把它们作为文本。

我正在用Python写作。有可能解决吗?谢谢!

4 个答案:

答案 0 :(得分:1)

我认为xml.sax不可能。 BeautifulSoup有SoupStrainer就是这么做的。如果您愿意使用该库,那么它很容易使用。

答案 1 :(得分:1)

它似乎不是由 xml.sax API 提供的,但您可以使用另一种中断控制流的方式:异常。

为此目的定义一个自定义异常:

class FinishedParsing(Exception):
    pass

完成解析后在处理程序中引发此异常并忽略它。

try:
    parser.parse(xml)
except FinishedParsing:
    pass

答案 2 :(得分:0)

这是使用SAX执行此操作的一种hackish方式。这会将内容保留在文本节点中。如果你需要在这些文本节点中保留标签和属性,它会变得更加复杂。

from xml.sax import handler, make_parser

class CustomContentHandler(handler.ContentHandler):

    def __init__(self):
        handler.ContentHandler.__init__(self)
        self.inside_text_tag = False
        self.text_content = []

    def startElement(self, name, attrs):
        if name == 'text':
            self.inside_text_tag = True

    def endElement(self, name):
        if name == 'text':
            self.inside_text_tag = False
            self.text = ''.join(self.text_content)
            print "%s" % (self.text)

    def characters(self, content):        
        if self.inside_text_tag:
            self.text_content.append(content)

def parse_file(filename):
    f = open(filename)
    parser = make_parser()
    ch = CustomContentHandler()
    parser.setContentHandler(ch)
    parser.parse(f)
    f.close()

if __name__ == "__main__":
    filename = "sample.xml"
    parse_file(filename)

用于以下sample.xml文件:

<tag1>
  <tag2>
    <title>XML</title>
    <text>
      Text001
      <h1>Header</h1>
      Text002
      <b>Text003</b>
    </text>
  </tag2>
</tag1>

会产生

Text001
Header
Text002
Text003

答案 3 :(得分:-1)

这就是CDATA部分的用途。

http://www.w3schools.com/xml/xml_cdata.asp

您可以使用libxml_saxlib来正确处理CDATA部分。

http://www.rexx.com/~dkuhlman/libxml_saxlib.html

更新:作为一个严格临时的解决方案,您可以预处理输入文件以使其成为有效的XML。例如,使用'sed'在适当的位置插入CDATA标记。<​​/ p>

这并不能解决实际问题,但是如果你幸运的话,会给你一个可解析的XML文件(例如,文件的非XML部分没有意外......)。