我能否告诉SAX解析器在某个元素处停止并将其子节点作为字符串获取?
我有一些比较大的XML文档,所以我不想用DOM来处理。不过在用SAX解析器解析文档时,我想在某个点停下来(比如说当我遇到一个特定名称的元素时),然后把那个元素里面的所有内容作为字符串获取。“所有内容”不一定是文本节点,它可能包含标签,但我不想解析这些标签,我只想把它们当作文本获取。
我是在用Python写代码。这个问题能解决吗?谢谢!
4 个回答
0
这里有一种比较“hack”的方法,可以使用SAX来实现。这种方法可以保留你文本节点中的内容。不过,如果你还想保留那些文本节点里的标签和属性,那就会变得更复杂了。
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
1
我觉得用 xml.sax
是不太可能做到这个的。BeautifulSoup 有个叫 SoupStrainer
的功能,正好可以实现这个。如果你愿意使用这个库,它其实很简单上手。
2
看起来在 xml.sax
这个API里没有提供直接的方法来中断控制流程,但你可以用另一种方式来实现:那就是使用异常。
你只需要定义一个自定义的异常来达到这个目的:
class FinishedParsing(Exception):
pass
当你完成解析时,在你的处理函数里抛出这个异常,然后就可以忽略它了。
try:
parser.parse(xml)
except FinishedParsing:
pass