我正在尝试使用 Python 解析 XML 文件。由于 XML 的大小,我想使用 Pull 解析器。我找到了这个一个。
我的代码以
开头doc = pulldom.parse("myfile.xml")
for event, node in doc:
# code here...
我正在使用
if (node.localName == "b"):
获取XML标签名称,效果很好。
我找不到如何从标签之间获取文本。使用
node.nodeValue
返回 None
。
我可以使用
node.toxml()
获取节点的完整 XML,但我只需要标签之间的文本。除了使用正则表达式替换将标签从 node.toxml()
中取出之外,还有其他方法可以做到这一点吗?
对于每个带有文本的标签,您有两个本地名称为“b”的节点 - 一个
START_ELEMENT
和一个 END_ELEMENT
。通常你应该收到这样的东西:
START_ELEMENT
CHARACTERS
END_ELEMENT
因此您正在寻找匹配的起始元素之后的字符。您可能想尝试这样的事情:
from xml.dom.pulldom import CHARACTERS, START_ELEMENT, parse
doc = parse("myfile.xml")
text_expected = False
for event, node in doc:
print event, node
if text_expected:
text_expected = False
if event != CHARACTERS:
# strange .. there should be some
continue
print node.data
else:
text_expected = (event == START_ELEMENT) and (node.localName == "b")
有了这个
myfile.xml
<a>
<b>c1</b>
<b>c2</b>
</a>
我得到了输出
c1
c2
请注意,您可能需要
strip()
每个字符串,并且必须忽略所有其他 CHARACTERS
事件。两个元素之间的每个换行符和空格都会生成一个 CHARACTERS
事件。
经过验证的答案带来了一些限制。
如果文本较长或超过一行,则会生成多个
CHARACTERS
事件。所以当前的代码会丢失一些文本。
如果输入是
<a>
<b>c1</b>
<b>c2
end</b>
</a>
输出仍然是
c1
c2
并且 end
丢失了。
这是一个处理多行内容的解决方案:
import sys
from xml.dom.pulldom import START_ELEMENT, END_ELEMENT, CHARACTERS, parse
doc = parse(sys.argv[1] if len(sys.argv)>1 else sys.stdin)
text_expected = False
for event, node in doc:
if text_expected and event == CHARACTERS:
print(node.data, end='') # prevent extra line break
elif (event == START_ELEMENT) and (node.localName == "b"):
text_expected = True
elif (event == END_ELEMENT) and (node.localName == "b"):
print("")
text_expected = False