Если вы хотите удалить 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, он имеетгораздо лучшая поддержка XPath, чем ElementTree.Вы также можете получить доступ к родительскому элементу с помощью 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())