Python 删除标签时出现 elementree 错误
Python elementree error when removing tags
我有这样的代码,用于从 root_compare 函数中的 xml 中删除所有名为 sysId 的标签:
#removing sysId from comparison
for rm1 in xml_root1.findall('.//sysId'):
xml_root1.remove(rm1)
代码给我这个错误:
File "/tmp/dev_uac_api2/uac_api_lib.py", line 105, in root_compare
xml_root1.remove(rm1)
File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 337, in remove
self._children.remove(element)
ValueError: list.remove(x): x not in list
我需要遍历 xml 中的所有元素,甚至子元素、孙元素,并删除名为 sysId 的元素。你能帮我解决这个问题吗?
xml 结构类似于:
<root>
<sysId></sysId>
<b></b>
<c>
<sysId></sysId>
</c>
<d>
<e>
<sysId></sysId>
</e>
</d>
</root>
在 ElementTree 中删除元素比在 lxml 中要多一些工作,因为 lxml 具有 getparent()
函数。
在 ElementTree 中,首先需要匹配要移除的元素的父元素。
ElementTree's xpath support 也不是很好,因此 .//*[sysId]
不会匹配第一个 sysId
元素,因为它是根元素的直接子元素。您必须单独删除它们。
示例...
import xml.etree.ElementTree as ET
xml = """<root>
<sysId></sysId>
<b></b>
<c>
<sysId></sysId>
</c>
<d>
<e>
<sysId></sysId>
</e>
</d>
</root>"""
root = ET.fromstring(xml)
# find/remove direct "sysId" children of root
for child in root.findall("sysId"):
root.remove(child)
# find elements that contain a "sysId" child element
for parent in root.findall(".//*[sysId]"):
# find/remove direct "sysId" children of parent
for child in parent.findall("sysId"):
parent.remove(child)
print ET.tostring(root)
打印输出...
<root>
<b />
<c>
</c>
<d>
<e>
</e>
</d>
</root>
这里有一个 lxml 的例子来显示差异(与上面相同的打印输出)...
from lxml import etree
xml = """<root>
<sysId></sysId>
<b></b>
<c>
<sysId></sysId>
</c>
<d>
<e>
<sysId></sysId>
</e>
</d>
</root>"""
root = etree.fromstring(xml)
for elem in root.xpath(".//sysId"):
elem.getparent().remove(elem)
print etree.tostring(root)
我有这样的代码,用于从 root_compare 函数中的 xml 中删除所有名为 sysId 的标签:
#removing sysId from comparison
for rm1 in xml_root1.findall('.//sysId'):
xml_root1.remove(rm1)
代码给我这个错误:
File "/tmp/dev_uac_api2/uac_api_lib.py", line 105, in root_compare
xml_root1.remove(rm1)
File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 337, in remove
self._children.remove(element)
ValueError: list.remove(x): x not in list
我需要遍历 xml 中的所有元素,甚至子元素、孙元素,并删除名为 sysId 的元素。你能帮我解决这个问题吗?
xml 结构类似于:
<root>
<sysId></sysId>
<b></b>
<c>
<sysId></sysId>
</c>
<d>
<e>
<sysId></sysId>
</e>
</d>
</root>
在 ElementTree 中删除元素比在 lxml 中要多一些工作,因为 lxml 具有 getparent()
函数。
在 ElementTree 中,首先需要匹配要移除的元素的父元素。
ElementTree's xpath support 也不是很好,因此 .//*[sysId]
不会匹配第一个 sysId
元素,因为它是根元素的直接子元素。您必须单独删除它们。
示例...
import xml.etree.ElementTree as ET
xml = """<root>
<sysId></sysId>
<b></b>
<c>
<sysId></sysId>
</c>
<d>
<e>
<sysId></sysId>
</e>
</d>
</root>"""
root = ET.fromstring(xml)
# find/remove direct "sysId" children of root
for child in root.findall("sysId"):
root.remove(child)
# find elements that contain a "sysId" child element
for parent in root.findall(".//*[sysId]"):
# find/remove direct "sysId" children of parent
for child in parent.findall("sysId"):
parent.remove(child)
print ET.tostring(root)
打印输出...
<root>
<b />
<c>
</c>
<d>
<e>
</e>
</d>
</root>
这里有一个 lxml 的例子来显示差异(与上面相同的打印输出)...
from lxml import etree
xml = """<root>
<sysId></sysId>
<b></b>
<c>
<sysId></sysId>
</c>
<d>
<e>
<sysId></sysId>
</e>
</d>
</root>"""
root = etree.fromstring(xml)
for elem in root.xpath(".//sysId"):
elem.getparent().remove(elem)
print etree.tostring(root)