3

我浏览了几篇帖子,但还没有找到任何可以解决我问题的答案。

示例 XML =

<TextWithNodes>
<Node id="0"/>TEXT1<Node id="19"/>TEXT2 <Node id="20"/>TEXT3<Node id="212"/>
</TextWithNodes>

所以我明白,通常如果我提取TextWithNodes为 aNodeList我会做类似的事情

nodeList = TextWithNodes[0].getElementsByTagName('Node')
for a in nodeList:
    node = a.nodeValue
    print node

我得到的只是None。我读过你必须写a.childNodes.nodeValue,但节点列表中没有子节点,因为看起来所有的NodeId 都是结束标签?如果我使用a.childNodes我得到[].

当我得到它的节点类型时,a它是类型 1 和TEXT_NODE= 3。我不确定这是否有帮助。

我想提取TEXT1,TEXT2等。

4

3 回答 3

2

lxml来自文档的解决方案:

from lxml import etree
from StringIO import StringIO

xml = etree.parse(StringIO('''<TextWithNodes>
<Node id="0"/>TEXT1<Node id="19"/>TEXT2 <Node id="20"/>TEXT3<Node id="212"/></TextWithNodes>'''))

xml.xpath("//text()")
Out[43]: ['\n', 'TEXT1', 'TEXT2 ', 'TEXT3']

您还可以提取特定节点的文本:

xml.find(".//Node[@id='19']").text

这里的问题是 XML 中的文本不属于任何节点。

于 2012-06-20T15:26:45.107 回答
1

您应该为您的任务使用 ElementTree api 而不是 minidom(如此处其他答案中所述),但如果您需要使用 minidom,这里有一个解决方案。

您要查找的内容已作为textContent属性添加到 DOM 级别 3 。Minidom 仅支持 1 级。

但是,您可以使用此函数非常接近地模拟 textContent:

def textContent(node):
    if node.nodeType in (node.TEXT_NODE, node.CDATA_SECTION_NODE):
        return node.nodeValue
    else:
        return ''.join(textContent(n) for n in node.childNodes)

然后您可以像这样使用它:

x = minidom.parseString("""<TextWithNodes>
<Node id="0"/>TEXT1<Node id="19"/>TEXT2 <Node id="20"/>TEXT3<Node id="212"/></TextWithNodes>""")

twn = x.getElementsByTagName('TextWithNodes')[0]

assert textContent(twn) == u'\nTEXT1TEXT2 TEXT3'

注意我是如何得到父节点的文本内容的TextWithNodes。这是因为您的Node元素是这些文本节点的兄弟姐妹,而不是它们的父节点。

于 2012-06-20T15:54:26.950 回答
0

使用xml.etree.ElemetTree(类似于@DiegoNavrro 在他的回答中使用的 lxml,除了标准库中的 etree 并且没有 XPATH 等),您可以尝试以下操作:

import xml.etree.ElementTree as etree

xml_string = """<TextWithNodes>
<Node id="0"/>TEXT1<Node id="19"/>TEXT2 <Node id="20"/>TEXT3<Node id="212"/>
</TextWithNodes>
"""

xml_etree = etree.fromstring(xml_string)

text = [element.tail for element in xml_etree]
# `text` will be ['TEXT1', 'TEXT2 ', 'TEXT3', '\n']

请注意,这假定 XML <Node id="0"/>TEXT1... 是正确的。因为文本跟在结束标签之后,所以它成为标签的尾部文本。它不是元素nodeValue,这就是为什么在你的问题代码中你得到Nones。

如果您想解析一些 XML <Node id="0">TEXT1</Node>,则必须将行替换[element.tail for element in xml_etree][element.text for element in xml_etree].

于 2012-06-20T15:43:40.880 回答