python - 如何使用 PYTHON 删除 XML 中的子元素/元素
问题描述
如果 XML 文件中有 2 个或更多条目,则需要一些帮助来删除 old(content[1]...[2]) "ns2:Comment"。每个实例我只需要 1 个“ns2:Comment”。
更新了示例 XML 以便更好地理解:
<?xml version="1.0" encoding="UTF-8"?>
<ns2:Audit >
<ns2:ProjectInfo>
<ns2:Name></ns2:Name>
<ns2:ProjectVersionId></ns2:ProjectVersionId>
<ns2:WriteDate>2020-01-09</ns2:WriteDate>
</ns2:ProjectInfo>
<ns2:IssueList>
<ns2:Issue instanceId="99999999999999" revision="0">
<ns2:ManagerAuditTrail></ns2:ManagerAuditTrail>
<ns2:ClientAuditTrail></ns2:ClientAuditTrail>
<ns2:ThreadedComments>
<ns2:Comment>
<ns2:Content>test</ns2:Content>
<ns2:Username>tester1</ns2:Username>
<ns2:Timestamp>2020-01-09</ns2:Timestamp>
</ns2:Comment>
<ns2:Comment>
<ns2:Content>test</ns2:Content>
<ns2:Username>tester2</ns2:Username>
<ns2:Timestamp>2020-01-09</ns2:Timestamp>
</ns2:Comment>
</ns2:ThreadedComments>
</ns2:Issue>
</ns2:Audit>
我创建的脚本:
import xml.etree.ElementTree as ET
tree = ET.parse('audit.xml')
root = tree.getroot()
for x in root[1]:
for thread in x:
for content in thread:
if content[1] is False and content[0] is True:
pass
else:
thread.remove(content)
tree.write('audit1.xml')
解决方案
您示例中的 XML 无效(开始和结束标记的顺序不匹配)。我不知道 ns2: 命名空间来自哪里,但是如果你想在 Etree 中加载它,你必须在根节点中定义那个命名空间。对于这个基于字符串的示例,我取出了 ns2 命名空间。
sample = """<Audit>
<ProjectInfo>
<IssueList>
<Comment>
<Content>test</Content>
<Username>tester</Username>
<Timestamp>2020-01-09</Timestamp>
</Comment>
<Comment>
<Content>test1</Content>
<Username>tester2</Username>
<Timestamp>2020-01-09T</Timestamp>
</Comment>
</IssueList>
</ProjectInfo>
</Audit>"""
如下导入该示例(作为字符串),使用 lxml 因为它更快:
from lxml import etree
tree = etree.fromstring(sample)
root = tree.getroottree()
现在,因为您要查找的评论是嵌套的,所以您也可以使用 Xpath 来获取它们,而不是循环它们。然后,您可以选择它们的父节点并删除索引为 1 或更高的那些的子节点。
commentlist = root.findall('//Comment')
for comment in commentlist[1:]:
comment.getparent().remove(comment)
etree.tostring(tree)
您必须对命名空间和使用文件进行一些编辑,但这个一般原则是有效的。如果您有很多要保留第一个 Comment 的 IssueList 节点,您可以使用 Xpath 选择所有这些节点,然后遍历子节点,丢弃除第一个之外的所有子节点。
issuelist = root.findall('//Issuelist')
for issue in issuelist:
first = True
for child in issue.getchildren:
if child.tag is 'Comment' and first is True:
First = false
continue
if child.tag is 'Comment' and first is False:
issue.remove(child)
etree.tostring(tree)
推荐阅读
- r - 边缘条件空白问题 R
- python - 如何在输入字符串中查找模式
- docker - 用于 ASP.NET Core 和 Visual Studio 2017 的 docker run 命令
- javascript - 如果购物车是空的,如何提醒用户?Javascript HTML
- dart - 在显示之前对从 StreamBuilder 获取的数据执行异步操作
- azure - azure api管理从shell脚本中检索密码,保存并部署它
- python - tkinter 画布文本输出
- mysql - 如何修复 SQL 中的“添加外键失败”
- python-2.7 - 如何退出原始输入提示
- python - 为什么“else”和“if”语句都在运行?