解决xml.etree移除XML子元素时remove()报TypeError问题
如何移除XML中指定索引位置的子元素
场景说明
需要移除示例XML第一个索引位置(即get_root_element[0]对应节点)下的name子元素,运行代码时抛出报错:TypeError: remove() argument must be xml.etree.ElementTree.Element, not dict,要求仅移除第一个<row>节点内的<name>子元素,其余节点内容保持不变。
原有错误代码
import xml.etree.ElementTree as ET parse_xml = ET.parse('/content/sample_data/xyz.xml') get_root_element = parse_xml.getroot() get_root_element[0].remove( get_root_element[0].attrib ) parse_xml.write('/content/sample_data/demo.xml')
报错原因
上述错误代码的传参完全不符合remove()方法的要求:
Element.attrib返回的是当前节点的属性字典,不是元素对象,因此触发类型错误- 需求是删除
<row>节点下的<name>子元素,和节点属性没有任何关系,传参目标本身就错了
xml.etree.ElementTree中remove()方法只接受当前节点的直接子元素对象作为参数,不支持传属性、标签名字符串等其他类型的值。
正确实现代码
先定位到目标父节点,再找到需要删除的对应子元素对象,传入remove()即可:
import xml.etree.ElementTree as ET parse_xml = ET.parse('/content/sample_data/xyz.xml') get_root_element = parse_xml.getroot() # 定位第一个row节点下的name直接子元素 target_child = get_root_element[0].find('name') # 传入元素对象执行删除 get_root_element[0].remove(target_child) # 写入时指定编码和xml声明,保证输出格式和原文件一致 parse_xml.write('/content/sample_data/demo.xml', encoding='utf-8', xml_declaration=True)
补充:如果目标父节点下存在多个同名直接子元素要删除,可以用
findall()方法拿到所有符合条件的元素对象,循环调用remove()即可。
示例源XML
<?xml version='1.0' encoding='utf-8'?> <data> <row> <index>0</index> <price>$5.95</price> <name>Belgian Waffles</name> <desc>Two of our famous Belgian Waffles with plenty of real maple syrup</desc> <calories>650</calories> </row> <row> <index>1</index> <price>$7.95</price> <name>Strawberry Belgian Waffles</name> <desc>Light Belgian waffles covered with strawberries and whipped cream</desc> <calories>900</calories> </row> <row> <index>2</index> <price>$8.95</price> <name>Berry-Berry Belgian Waffles</name> <desc>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</desc> <calories>900</calories> </row> <row> <index>3</index> <price>$4.50</price> <name>French Toast</name> <desc>Thick slices made from our homemade sourdough bread</desc> <calories>600</calories> </row> <row> <index>4</index> <price>$6.95</price> <name>Homestyle Breakfast</name> <desc>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</desc> <calories>950</calories> </row> </data>
输出结果
执行代码后,仅第一个<row>节点下的<name>元素被移除,其余节点完全保留,输出内容如下:
<?xml version='1.0' encoding='utf-8'?> <data> <row> <index>0</index> <price>$5.95</price> <desc>Two of our famous Belgian Waffles with plenty of real maple syrup</desc> <calories>650</calories> </row> <row> <index>1</index> <price>$7.95</price> <name>Strawberry Belgian Waffles</name> <desc>Light Belgian waffles covered with strawberries and whipped cream</desc> <calories>900</calories> </row> <row> <index>2</index> <price>$8.95</price> <name>Berry-Berry Belgian Waffles</name> <desc>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</desc> <calories>900</calories> </row> <row> <index>3</index> <price>$4.50</price> <name>French Toast</name> <desc>Thick slices made from our homemade sourdough bread</desc> <calories>600</calories> </row> <row> <index>4</index> <price>$6.95</price> <name>Homestyle Breakfast</name> <desc>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</desc> <calories>950</calories> </row> </data>
内容的提问来源于stack exchange,提问作者kiric8494
相关产品推荐
相关产品推荐

