Python ElementTree 添加一个 child

Python ElementTree adding a child

我有一个 xml 文件,如下所示:

<keyboard>
 
</keyboard>

我想让它看起来像这样:

<keyboard>
    
    <keybind key="W-c-a"><action name="Execute"><command>sudo shutdown now</command></action></keybind>

</keyboard>

我有一个函数可以添加这个,它有可以改变键和命令的参数。这可能吗?如果是,我该怎么做?

(函数):

def add_keybinding(self, keys, whatToExec):
        
        keybinding = "<keybind key=\"%s\"><action name=\"Execute\"><command>%s</command><action></keybind>" % (keys, whatToExec)
        f = open("/etc/xdg/openbox/rc.xml", "a")
        try:
            # I want to append the keybinding variable to the <keyboard>
        except IOError as e:
            print(e)

来自 doc,您可以尝试以下操作:

def add_keybinding(keys, whatToExec, filename): 
    keybind = ET.Element('keybind')
    keybind.set("key", keys)

    action = ET.SubElement(keybind, 'action')
    action.set("name", "Execute")
    
    command = ET.SubElement(action, 'command')
    command.text = whatToExec

    tree = ET.parse(filename)
    tree.getroot().append(keybind)
    
    tree.write(filename)

解释:

  1. 使用 xml.etree.ElementTree.Element 创建 keybind 标签:keybind = ET.Element('keybind')
  2. 设置 属性 使用 set: keybind.set("key", keys)
  3. 创建 action 标签作为 keybind 的子元素,使用 xml.etree.ElementTree.SubElement: action = ET.SubElement(keybind, 'action')
  4. 设置 属性 与第 2 步相同:action.set("name", "Execute")
  5. 创建命令 标签:action.set("name", "Execute")
  6. 使用.text设置command标签内容:command.text = whatToExec
  7. 使用xml.etree.ElementTree.parse读取文件:tree = ET.parse(filename)
  8. 使用 append*
  9. keybind 标记附加到文档根元素
  10. 使用write
  11. 导出新的xml到文件

完整示例:

import xml.etree.ElementTree as ET
from xml.dom import minidom

def add_keybinding(keys, whatToExec, filename): 
    keybind = ET.Element('keybind')
    keybind.set("key", keys)

    action = ET.SubElement(keybind, 'action')
    action.set("name", "Execute")
    
    command = ET.SubElement(action, 'command')
    command.text = whatToExec

    tree = ET.parse(filename)
    tree.getroot().append(keybind)
    
    tree.write(filename)
    return tree

def prettify(elem):
    rough_string = ET.tostring(elem, 'utf-8')
    return minidom.parseString(rough_string).toprettyxml(indent="  ")

filename = "test.xml"
for i in range(3):
    tree = add_keybinding(str(i), "whatToExec " + str(i), filename)
    
print(prettify(tree.getroot()))

输出:

<?xml version="1.0" ?>
<keyboard>
  <keybind key="0">
    <action name="Execute">
      <command>whatToExec 0</command>
    </action>
  </keybind>
  <keybind key="1">
    <action name="Execute">
      <command>whatToExec 1</command>
    </action>
  </keybind>
  <keybind key="2">
    <action name="Execute">
      <command>whatToExec 2</command>
    </action>
  </keybind>
</keyboard>