Python 和 XML 解析、修改、保存

Python and XML parsing, modifying, saving

我有一个 xml 文件,其中包含用于控制设备的 GUI 应用程序的默认设置:

    <Settings>
        <Setting Name="Frame0_TypeTextBox" Type="UpDown" UpDownType="d">1</Setting>
        <Setting Name="Frame1_TypeTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="Frame2_TypeTextBox" Type="UpDown" UpDownType="d">1</Setting>
        <Setting Name="messageTypeBoxManual" Type="ComboBox" UpDownType="">4</Setting>
        <Setting Name="Frame0_C1CounterTextBox" Type="UpDown" UpDownType="Hex">0015E0</Setting>
        <Setting Name="Frame1_C1CounterTextBox" Type="UpDown" UpDownType="Hex">0015E0</Setting>
        <Setting Name="Frame2_C1CounterTextBox" Type="UpDown" UpDownType="Hex">0015E0</Setting>
        <Setting Name="Frame0_CtrlMsgTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="Frame1_CtrlMsgTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="Frame2_CtrlMsgTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="rxSeedBox" Type="UpDown" UpDownType="Hex">03777777</Setting>
        <Setting Name="txSeedBox" Type="UpDown" UpDownType="Hex">03777777</Setting>
        <Setting Name="forceRxSeed" Type="CheckBox" UpDownType="">False</Setting>
    </Settings>

还有几百个设置,但它们都遵循相同的约定,这个文件是由我提到的应用程序生成的,必须保留布局以便应用程序再次读取它。

我想做的是:

1) 阅读XML

2) 查找 Name="rxSeedBox" 和 "txSeedBox" 的字段(设置名称是唯一的)

3) 将它们的值从 03777777 编辑为其他值,例如分别为 05FFFFFF 和 08E243AF

4) 保存修改后的 xml 以便在应用程序中加载

目前的代码如下:

import sys
import os
import time
import xml.etree.ElementTree as ET
from socket import * # portable socket interface plus constants

tree = ET.parse('txg.xml')
root = tree.getroot()

for Setting in root.findall('Setting'):
    Name = Setting.get('Name')
    Type = Setting.get('Type')
    UpDownType = Setting.get('UpDownType')
    print(Name, Type, UpDownType, Setting.text)

此时它所做的几乎所有工作都是从文件中读取 XML 并打印其内容。 我不知道要搜索特定的、唯一的 Name 属性然后更改值。 我试过

value = tree.findtext('Setting') 

命令,但到目前为止我看到的唯一用法是更改属性。

我希望属性保持不变,但要更改标签之间的值。 我如何使用 ElementTree 做到这一点?

您提出的建议似乎很有效。只需找到您要更改的那个并更改它即可:

import sys
import os
import time
import xml.etree.ElementTree as ET

txg = """
    <Settings>
        <Setting Name="Frame0_TypeTextBox" Type="UpDown" UpDownType="d">1</Setting>
        <Setting Name="Frame1_TypeTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="Frame2_TypeTextBox" Type="UpDown" UpDownType="d">1</Setting>
        <Setting Name="messageTypeBoxManual" Type="ComboBox" UpDownType="">4</Setting>
        <Setting Name="Frame0_C1CounterTextBox" Type="UpDown" UpDownType="Hex">0015E0</Setting>
        <Setting Name="Frame1_C1CounterTextBox" Type="UpDown" UpDownType="Hex">0015E0</Setting>
        <Setting Name="Frame2_C1CounterTextBox" Type="UpDown" UpDownType="Hex">0015E0</Setting>
        <Setting Name="Frame0_CtrlMsgTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="Frame1_CtrlMsgTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="Frame2_CtrlMsgTextBox" Type="UpDown" UpDownType="d">2</Setting>
        <Setting Name="rxSeedBox" Type="UpDown" UpDownType="Hex">03777777</Setting>
        <Setting Name="txSeedBox" Type="UpDown" UpDownType="Hex">03777777</Setting>
        <Setting Name="forceRxSeed" Type="CheckBox" UpDownType="">False</Setting>
    </Settings>
"""

tree = ET.ElementTree(ET.fromstring(txg))
root = tree.getroot()

for Setting in root.findall('Setting'):
    Name = Setting.get('Name')
    Type = Setting.get('Type')
    UpDownType = Setting.get('UpDownType')
    print(Name, Type, UpDownType, Setting.text)

print

for Setting in root.findall('Setting'):
    if Setting.get('Name') == 'rxSeedBox':
      Setting.text = '05FFFFFF'

for Setting in root.findall('Setting'):
    Name = Setting.get('Name')
    Type = Setting.get('Type')
    UpDownType = Setting.get('UpDownType')
    print(Name, Type, UpDownType, Setting.text)

你得到以下输出

('Frame0_TypeTextBox', 'UpDown', 'd', '1')
('Frame1_TypeTextBox', 'UpDown', 'd', '2')
('Frame2_TypeTextBox', 'UpDown', 'd', '1')
('messageTypeBoxManual', 'ComboBox', '', '4')
('Frame0_C1CounterTextBox', 'UpDown', 'Hex', '0015E0')
('Frame1_C1CounterTextBox', 'UpDown', 'Hex', '0015E0')
('Frame2_C1CounterTextBox', 'UpDown', 'Hex', '0015E0')
('Frame0_CtrlMsgTextBox', 'UpDown', 'd', '2')
('Frame1_CtrlMsgTextBox', 'UpDown', 'd', '2')
('Frame2_CtrlMsgTextBox', 'UpDown', 'd', '2')
('rxSeedBox', 'UpDown', 'Hex', '03777777')
('txSeedBox', 'UpDown', 'Hex', '03777777')
('forceRxSeed', 'CheckBox', '', 'False')

('Frame0_TypeTextBox', 'UpDown', 'd', '1')
('Frame1_TypeTextBox', 'UpDown', 'd', '2')
('Frame2_TypeTextBox', 'UpDown', 'd', '1')
('messageTypeBoxManual', 'ComboBox', '', '4')
('Frame0_C1CounterTextBox', 'UpDown', 'Hex', '0015E0')
('Frame1_C1CounterTextBox', 'UpDown', 'Hex', '0015E0')
('Frame2_C1CounterTextBox', 'UpDown', 'Hex', '0015E0')
('Frame0_CtrlMsgTextBox', 'UpDown', 'd', '2')
('Frame1_CtrlMsgTextBox', 'UpDown', 'd', '2')
('Frame2_CtrlMsgTextBox', 'UpDown', 'd', '2')
('rxSeedBox', 'UpDown', 'Hex', '05FFFFFF')
('txSeedBox', 'UpDown', 'Hex', '03777777')
('forceRxSeed', 'CheckBox', '', 'False')

那么,当您将其打印为 xml 格式时,您可能正在更改格式。 ElementTree 有时会发生这种情况。您可以查看以您准备的格式打印此文件的方法,例如在 Pretty printing XML in Python 中使用 xml.etree.elementtree 写出格式良好的 xml 文件 [重复]