使用minidom从子节点获取值

0 投票
3 回答
5299 浏览
提问于 2025-04-16 23:13

我对XML还很陌生,现在想从子节点中获取值。

from xml.dom import minidom

def Get_ExtList(progName):
    progFile='%s.xml'%progName
    xmldoc = minidom.parse(progFile)
    extList=[]
    rootNode=xmldoc.firstChild
    progNode=rootNode.childNodes[1]
    for fileNodes in progNode.childNodes:
        newList=[]      
        for formatNodes in fileNodes.childNodes:        
            for nodes in formatNodes.childNodes:
                x=nodes.toxml()
                x=' '.join(x.split())
                newList.append(str(x))
        extList.append(newList)     
    print extList

输出结果:

[[], [‘.aaa'], [], [‘.bbb'], [], [‘.ccc'], [], [‘.ddd'], [], [‘.xxx', ‘.yyy'], []]

但我想要的结果是这样的:

[[‘.aaa'], [‘.bbb'],[‘.ccc’],[‘.ddd'],[‘.xxx', ‘.yyy']]

这里有一个示例文件:

<?xml version="1.0" ?>
<program>
  <progname name="TEST">
    <file>
      <format>
        .aaa
      </format>
    </file>
    <file>
      <format>
        .bbb
      </format>
    </file>
    <file>
      <format>
        .ccc
      </format>
    </file>
    <file>
      <format>
        .ddd
      </format>
    </file>
    <file>
      <format>
        .xxx
      </format>
      <format>
        .yyy
      </format>
    </file>
  </progname>
</program>

3 个回答

0

在这种情况下,你可以尝试处理这个列表,删除里面的空元素:

>>> list = [[], ['.inp'], [], ['.mdp'], [], ['.xtc'], [], ['.top'], [], ['.gro', '.pdb'], []]
>>> for i in list:
...   if not i:
...     list.remove(i)
... 
>>> list
[['.inp'], ['.mdp'], ['.xtc'], ['.top'], ['.gro', '.pdb']]
0

DOM节点可以是元素、文本,甚至是注释。还有一点要注意的是,toxml不应该用来提取文本内容。相反,应该使用文本节点的.data属性:

for nodes in formatNodes.childNodes:
    if node.nodeType == node.ELEMENT_NODE:
        tns =(tn.data for tn in node.childNodes if tn.nodeType == node.TEXT_NODE)
        newList.append(''.join(tns).strip())
1

你在循环的时候,不仅在遍历包含 <file> 标签的节点(也就是 ELEMENT_NODE 类型),还在遍历一些空格和缩进(也就是 TEXT_NODE 类型)。举个例子,在这个元素中:

<a>
  <b>c</b>
</a>

里面有三个元素:

  • 一个 TEXT_NODE,值是 \n__(空格用 _ 表示)
  • 一个 ELEMENT_NODE,值是 <b>c</b>
  • 另一个 TEXT_NODE,值是 \n

如果这个文件的格式不一样,比如写成 <a><b>c</b></a>,那么里面就只有一个 ELEMENT_NODE 了。

你可以选择跳过这些节点:

for fileNodes in progNode.childNodes:    
    if fileNodes.nodeType != fileNodes.ELEMENT_NODE:    
        continue

或者检查一下 newList 是否是为正确的节点创建的,只把内容添加到 ELEMENT_NODE 中:

    if fileNodes.nodeType == fileNodes.ELEMENT_NODE:    
        extList.append(newList)         

否则你会得到一个空列表 [] 被添加上去。

撰写回答