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

In Python, how can I inspect a specific section of XML and extract the node text?

我正在使用 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 部分的两种布局,以及到处都是的多个 Item 子元素。

用 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] 将我限制为 Item in Keys 的第一次出现。

那么,有没有一种方法可以让我检查顶级项目及其所有子元素,拉出单个 CommandName 和该顶级项目中的所有键项目,然后再继续下一个项目顶级项目并重复该过程?到目前为止,我完全没有做到这一点。

我应该使用 ElementTree 吗?

非常感谢。

我无法发表评论,因为我低于阈值所以请原谅我把这个作为答案

是的,您应该按照我在此处

上找到的 link 使用元素树

Python Minidom XML Query

我没有使用 minidom 的经验,建议

It's use is not recommended, you probably want to use xml.etree.ElementTree instead.

-- 来自 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']