在Python中,我如何检查XML的特定部分并提取节点文本?

时间:2017-08-01 18:26:16

标签: python xml minidom

我使用minidom检查包含调试密钥列表列表的XML。 XML的一个例子如下:

<Shortcuts>
  <Item>
    <CommandName>DebugCommandName_1</CommandName>
    <ShortcutKeys>
      <Item>
        <Keys>
          <Item>KEY_1</Item>
          <Item>KEY_2</Item>
        </Keys>
      </Item>
    </ShortcutKeys>
  </Item>
...
  <Item>
    <CommandName>DebugCommandName_2</CommandName>
    <ShortcutKeys>
      <Item>
        <Keys>
          <Item>KEY_3</Item>
        </Keys>
      </Item>
      <Item>
        <Keys>
          <Item>KEY_4</Item>
        </Keys>
      </Item>
    </ShortcutKeys>
  </Item>
</Shortcuts>

由于我无法控制的原因,我将无法要求将传入XML的格式更改为更一致,因此我必须考虑文档的ShortcutKeys部分的两种布局,以及多项孩子们到处都是。

使用minidom解析XML,然后使用以下Python提取内容:

for item in parsedKeyComboFile.getElementsByTagName("Item"):
if (item.getElementsByTagName("CommandName").length > 0): 
    commandName = item.getElementsByTagName("CommandName")[0].childNodes[0].nodeValue
    print(commandName)
elif (item.getElementsByTagName("Keys").length > 0):
    keyCombo = item.getElementsByTagName("Item")[0].childNodes[0].nodeValue
    print(keyCombo)

我最终会将这些信息添加到字典中,但是现在我打印出的上述XML是:

DebugCommandName_1
KEY_1
DebugCommandName_2
KEY_3
KEY_4

当我想要的是:

DebugCommandName_1
KEY_1 KEY_2
DebugCommandName_2
KEY_3 KEY_4

(我意识到我没有正确格式化键的打印以实现单行输出。这里关键的是不跳过KEY_2项。)

我知道keyCombo =行中的[0]限制了我第一次出现在Keys中的Item。

那么,有没有办法让我检查顶级Item及其所有子元素,拉出单个CommandName和顶级Item中的所有Keys Items,然后再转到下一个顶级项目并重复这个过程?到目前为止,我完全没有达到目的。

我应该使用ElementTree吗?

非常感谢。

2 个答案:

答案 0 :(得分:1)

我没有使用minidom和推荐

的经验
  

不推荐使用它,您可能希望改为使用xml.etree.ElementTree

- 来自minidom代码信息

如果您可以使用xml.etree.ElementTree代替,这可能是一种直截了当的方式:

import xml.etree.ElementTree as ET
tree = ET.parse('example.xml')
root = tree.getroot()  # unused variable in this example

for elem in tree.iter():
    if elem.tag == 'CommandName':
        print(elem.text)
    if elem.tag == 'Keys': 
        for item in elem:
            print(item.text)

打印

DebugCommandName_1
KEY_1
KEY_2
DebugCommandName_2
KEY_3
KEY_4

或者,如果您需要每个<Keys>代码的列表:

if elem.tag == 'Keys':
    print([item.text for item in elem])

打印:

DebugCommandName_1
['KEY_1', 'KEY_2']
DebugCommandName_2
['KEY_3']
['KEY_4']

答案 1 :(得分:0)

我无法评论,因为我低于门槛,所以请原谅我把这个作为答案

是的,您应该根据我在此处找到的链接使用元素树

jQuery API documentation