如何用Python的etree XMLPullParser获取所有文本节点?
关于XMLPullParser获取所有文本节点的问题
我尝试用Python的etree XMLPullParser做非阻塞XML解析,但这个解析器不会把文本节点作为事件上报,官方说明它仅支持"start"、"end"、"comment"、"pi"、"start-ns"和"end-ns"这些事件。现在我想从元素事件里获取文本,但只能拿到每个元素的第一个文本节点,比如示例里的"text3"就获取不到,请问XMLPullParser能不能获取所有文本节点?怎么改代码拿到"text3"?
示例代码:
import xml.etree.ElementTree as ET # It seems "text3" cannot be accessed by the following code?! xml = "<a>text1<b>text2</b>text3</a>" # There is no "text" or "characters" event type. # All we can access is start-element and end-element. eventsToHandle = ["start", "end"] parser = ET.XMLPullParser(eventsToHandle) # There is no "text3" in the output. parser.feed(xml) for e, x in parser.read_events(): print(e, f"<{x.tag}>", f"(text: {x.text})")
当前输出(无"text3"):
start <a> (text: text1) start <b> (text: text2) end <b> (text: text2) end <a> (text: text1)
解决方案
XMLPullParser确实没有专门的文本节点事件,但可以通过元素的**tail属性**捕获后续文本——也就是当前元素结束标签之后、下一个元素(或父元素结束标签)之前的内容。
你的示例中,<b>元素的tail属性就是"text3",修改代码时同时打印text和tail即可:
修改后的代码:
import xml.etree.ElementTree as ET xml = "<a>text1<b>text2</b>text3</a>" eventsToHandle = ["start", "end"] parser = ET.XMLPullParser(eventsToHandle) parser.feed(xml) for e, x in parser.read_events(): log = f"{e} <{x.tag}>" if x.text: log += f" (text: {x.text})" if x.tail: log += f" (tail: {x.tail})" print(log)
修改后的输出:
start <a> (text: text1) start <b> (text: text2) end <b> (text: text2) (tail: text3) end <a> (text: text1)
关键说明
element.text:元素开始标签后、第一个子元素(或结束标签)前的文本element.tail:元素结束标签后、下一个元素(或父元素结束标签)前的文本
通过同时处理这两个属性,就能捕获XML中所有分散的文本内容。
内容的提问来源于stack exchange,提问作者Presidio Vantage
相关产品推荐
相关产品推荐

