python - 删除 XML 中的容器
问题描述
这是我的输入文件。故意留下标题,因为我认为它们与问题无关。我没有粘贴整个文件,因为它很大。我只添加了两个容器:
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>ABC</SHORT-NAME>
<DEFINITION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject</DEFINITION-REF>
<PARAMETER-VALUES>
<ECUC-NUMERICAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-INTEGER-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue</DEFINITION-REF>
<VALUE>1053</VALUE>
</ECUC-NUMERICAL-PARAM-VALUES>
<ECUC-TEXTUAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-ENUMERATION-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANHandleType</DEFINITION-REF>
<VALUE>TRUE</VALUE>
</ECUC-TEXTUAL-PARAM-VALUES>
</PARAMETER-VALUES>
<ECUC-CONTAINER-VALUE>
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>ABC</SHORT-NAME>
<DEFINITION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject</DEFINITION-REF>
<PARAMETER-VALUES>
<ECUC-NUMERICAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-INTEGER-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue</DEFINITION-REF>
<VALUE>1054</VALUE>
</ECUC-NUMERICAL-PARAM-VALUES>
<ECUC-TEXTUAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-ENUMERATION-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANHandleType</DEFINITION-REF>
<VALUE>FALSE</VALUE>
</ECUC-TEXTUAL-PARAM-VALUES>
</PARAMETER-VALUES>
<ECUC-CONTAINER-VALUE>
我的 xml 中有大约 100 个<ECUC-CONTAINER-VALUE>
标签。如果容器下面<ECUC-NUMERICAL-PARAM-VALUES>
的文本是,我必须删除容器
但我没有得到结果。请帮助。<DEFINITION-REF DEST="ECUC-INTEGER-PARAM-DEF">
/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue
我写的脚本:
import xml.etree.ElementTree
tree = ET.parse('a.xml')
root = tree.getroot()
for child in root.findall(".//ECUC-NUMERICAL-PARAM-VALUE"):
for gchild in child.findall(".//DEFINITION-REF [@DEST='ECUC-INTEGER-PARAM-DEF']"):
string = gchild.find("VALUE").text
if string == "/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue":
root.remove(child)
解决方案
如果要删除ECUC-NUMERICAL-PARAM-VALUES
,则需要选择它的父级。所以尝试从PARAMETER-VALUES
关卡中进行迭代。
例子...
XML 输入(a.xml
;更新为格式正确)
<doc>
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>ABC</SHORT-NAME>
<DEFINITION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject</DEFINITION-REF>
<PARAMETER-VALUES>
<ECUC-NUMERICAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-INTEGER-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue</DEFINITION-REF>
<VALUE>1053</VALUE>
</ECUC-NUMERICAL-PARAM-VALUES>
<ECUC-TEXTUAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-ENUMERATION-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANHandleType</DEFINITION-REF>
<VALUE>TRUE</VALUE>
</ECUC-TEXTUAL-PARAM-VALUES>
</PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>ABC</SHORT-NAME>
<DEFINITION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject</DEFINITION-REF>
<PARAMETER-VALUES>
<ECUC-NUMERICAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-INTEGER-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue</DEFINITION-REF>
<VALUE>1054</VALUE>
</ECUC-NUMERICAL-PARAM-VALUES>
<ECUC-TEXTUAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-ENUMERATION-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANHandleType</DEFINITION-REF>
<VALUE>FALSE</VALUE>
</ECUC-TEXTUAL-PARAM-VALUES>
</PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>
</doc>
Python
import xml.etree.ElementTree as ET
tree = ET.parse('a.xml')
for p_vals in tree.findall(".//PARAMETER-VALUES"):
for num_p_vals in p_vals.findall(".//ECUC-NUMERICAL-PARAM-VALUES"):
def_ref = num_p_vals.find("DEFINITION-REF[@DEST='ECUC-INTEGER-PARAM-DEF']")
if def_ref is not None and def_ref.text == \
"/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue":
p_vals.remove(num_p_vals)
ET.dump(tree)
输出
<doc>
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>ABC</SHORT-NAME>
<DEFINITION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject</DEFINITION-REF>
<PARAMETER-VALUES>
<ECUC-TEXTUAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-ENUMERATION-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANHandleType</DEFINITION-REF>
<VALUE>TRUE</VALUE>
</ECUC-TEXTUAL-PARAM-VALUES>
</PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>ABC</SHORT-NAME>
<DEFINITION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject</DEFINITION-REF>
<PARAMETER-VALUES>
<ECUC-TEXTUAL-PARAM-VALUES>
<DEFINITION-REF DEST="ECUC-ENUMERATION-PARAM-DEF">/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANHandleType</DEFINITION-REF>
<VALUE>FALSE</VALUE>
</ECUC-TEXTUAL-PARAM-VALUES>
</PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>
</doc>
如果您能够使用 lxml,它比 ElementTree 具有更好的 XPath 支持。您还可以使用 访问父元素getparent()
。在我看来,这简化了答案。
示例...(与上述相同的输入产生与上述相同的输出)
from lxml import etree
tree = etree.parse('a.xml')
for num_p_vals in tree.xpath(".//ECUC-NUMERICAL-PARAM-VALUES[DEFINITION-REF[@DEST='ECUC-INTEGER-PARAM-DEF']='/AUTOSAR_CAN/EcucModuleDefs/CanConfigSet/CanHardwareObject/CANIdValue']"):
num_p_vals.getparent().remove(num_p_vals)
etree.dump(tree.getroot())
推荐阅读
- postgresql - 在 dockerized flask + postgres 应用程序中管理 pytest 测试的任何推荐方法?
- javascript - 在 iframe 中结合 2 个 onload 命令
- php - 将数组与公共键组合以进行 MYSQL 更新
- hash - 区块链散列中如何计算印章号?
- google-oauth - 登录服务器端应用程序并弃用
- php - Magento 2.2.2 错误:配置文件已更改。运行 app:config:import 或 setup:upgrade 命令同步配置
- laravel - 我的 Laravel 容器中的路由没有更新
- android - 构建一个 android 客户端应用程序以与支持 HTTP2 的流服务交互
- c - 无法将较小的数组复制到 C 中较大的预填充数组中
- robocopy - Robocopy - 错误 124 (0x0000007C) 创建目标目录