Python XML Pull 解析器

问题描述 投票:0回答:2

我正在尝试使用 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()
中取出之外,还有其他方法可以做到这一点吗?

python xml xml-parsing xmlpullparser
2个回答
1
投票

对于每个带有文本的标签,您有两个本地名称为“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
事件。


0
投票

经过验证的答案带来了一些限制。

如果文本较长或超过一行,则会生成多个

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
© www.soinside.com 2019 - 2024. All rights reserved.