我已经浏览了几篇帖子,但我还没有找到任何解决我问题的答案。
示例 XML =
<TextWithNodes>
<Node id="0"/>TEXT1<Node id="19"/>TEXT2 <Node id="20"/>TEXT3<Node id="212"/>
</TextWithNodes>
所以我明白,通常如果我提取TextWithNodes
作为NodeList
我会做类似的事情
nodeList = TextWithNodes[0].getElementsByTagName('Node')
for a in nodeList:
node = a.nodeValue
print node
我得到的只是None
.我读过您必须写a.childNodes.nodeValue
但节点列表中没有子节点,因为看起来所有 Node
Id 都是结束标签?如果我使用a.childNodes
我会得到[]
.
当我获得a
的节点类型时,它是类型 1 和 TEXT_NODE
= 3。我不确定这是否有帮助。
我想提取TEXT1
、TEXT2
等。
文档中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 中的文本不属于任何节点。
你应该使用ElementTree api而不是minidom来完成你的任务(如这里其他答案中所解释的),但如果你需要使用minidom,这里有一个解决方案。
您要查找的内容已作为 textContent
属性添加到 DOM 级别 3。 迷你圈仅支持级别 1。
但是,您可以使用此函数非常接近地模拟文本内容:
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
元素是这些文本节点的同级,而不是它们的父级。
使用 xml.etree.ElemetTree
(类似于 lxml,@DiegoNavrro在他的答案中使用,除了标准库中的一部分 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,这就是为什么在你的代码中的问题中你会得到None
s。
如果要解析某些 XML,例如<Node id="0">TEXT1</Node>
则必须将行[element.tail for element in xml_etree]
替换为 [element.text for element in xml_etree]
。