如何使用 python 根据条件删除 xml 文件中的特定行?
How to delete a particular line in xml file based on the condition using python?
我有问题,正在寻找解决方案。
我想删除该行,但基于条件。例如 xml 文件是
<app>
.
.
<process>
<tag>any tag</tag>
<trigger order="1" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="3" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="2" name="activity1" perform="y">
<external>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="1" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="4" name="activity1" perform="y">
<external>
<action name="ckeck"/>
<action name="check_req"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
</app>
所以我想从这段代码中删除行 <action name="ckeck"/>
每当触发器中存在这两个动作时
<action name="ckeck"/>
<action name="ckeck_req"/>
或
<action name="ckeck_req"/>
<action name="ckeck"/>
所以我必须删除行 <action name="ckeck"/>
只有在上述两个操作同时发生的情况下,否则它不会删除任何行。
我是 python 语言的新手,所以我无法执行此操作。问题是文件包含很多触发块,其中一些包含操作块,而一些只包含一个操作块。特定行仅在给定情况发生时删除
你应该使用一些 xml 解析库,比如 xml.etree.ElementTree
或 lxml
。
然后就可以使用XPATH找到<trigger>
下的所有<external>
元素,然后得到名字为[=的action
元素45=] 作为 check_req
和 action
名称为 属性 的元素作为 ckeck
。然后如果两者都不是 none,这意味着两个孩子都存在,删除其名称属性为 ckeck
的元素,然后将 xml 保存回其他文件(甚至同一个文件) ).例子-
import xml.etree.ElementTree as ET
file = ET.parse('a.xml')
root = file.getroot()
for elem in root.findall('.//trigger/external'):
check_req_elems = elem.find('./action[@name="check_req"]')
check_elem = elem.find('./action[@name="ckeck"]')
if check_req_elems is not None and check_elem is not None:
elem.remove(check_elem)
file.write('b.xml')
Example/Demo -
我的a.xml
-
<app>
<process>
<tag>any tag</tag>
<trigger order="3" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>>
<process>
<tag>any tag</tag>
<trigger order="2" name="activity1" perform="y">
<external>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
</app>
代码-
>>> file = ET.parse('a.xml')
>>> root = file.getroot()
>>> for elem in root.findall('.//trigger/external'):
... check_req_elems = elem.find('.//action[@name="check_req"]')
... check_elem = elem.find('.//action[@name="ckeck"]')
... if check_req_elems is not None and check_elem is not None:
... elem.remove(check_elem)
...
>>> file.write('b.xml')
我的b.xml
变成-
<app>
<process>
<tag>any tag</tag>
<trigger name="activity1" order="3" perform="y">
<external>
<action name="check_req" />
<action name="event" />
</external>
<var name="type" />
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger name="activity1" order="2" perform="y">
<external>
<action name="event" />
<action name="ckeck" />
</external>
<var name="type" />
<var name="user" />
</trigger>
</process>
</app>
当两个动作在触发器中出现时,它们是否总是以相同的方式排序,即 "ckeck" 在 "ckeck_req" 之后并且相隔一行?如果是这种情况,您可以基于此给出条件,例如
action1 = "ckeck_req"
action2 = "ckeck"
with open(xmlfile, "r") as f:
x = f.readlines()
y = [] # new list without the unwanted actions
for i in range(len(x)):
if action2 in x[i] and action1 in x[i-2]:
continue
else:
y.append(x[i])
然后将新列表y写入文件。我只是在脑海中写下了这一点,所以很可能有更好的方法来做到这一点。现在我考虑了一下,您可能想看看 Regular Expressions.
我有问题,正在寻找解决方案。
我想删除该行,但基于条件。例如 xml 文件是
<app>
.
.
<process>
<tag>any tag</tag>
<trigger order="1" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="3" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="2" name="activity1" perform="y">
<external>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="1" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger order="4" name="activity1" perform="y">
<external>
<action name="ckeck"/>
<action name="check_req"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
</app>
所以我想从这段代码中删除行 <action name="ckeck"/>
每当触发器中存在这两个动作时
<action name="ckeck"/>
<action name="ckeck_req"/>
或
<action name="ckeck_req"/>
<action name="ckeck"/>
所以我必须删除行 <action name="ckeck"/>
只有在上述两个操作同时发生的情况下,否则它不会删除任何行。
我是 python 语言的新手,所以我无法执行此操作。问题是文件包含很多触发块,其中一些包含操作块,而一些只包含一个操作块。特定行仅在给定情况发生时删除
你应该使用一些 xml 解析库,比如 xml.etree.ElementTree
或 lxml
。
然后就可以使用XPATH找到<trigger>
下的所有<external>
元素,然后得到名字为[=的action
元素45=] 作为 check_req
和 action
名称为 属性 的元素作为 ckeck
。然后如果两者都不是 none,这意味着两个孩子都存在,删除其名称属性为 ckeck
的元素,然后将 xml 保存回其他文件(甚至同一个文件) ).例子-
import xml.etree.ElementTree as ET
file = ET.parse('a.xml')
root = file.getroot()
for elem in root.findall('.//trigger/external'):
check_req_elems = elem.find('./action[@name="check_req"]')
check_elem = elem.find('./action[@name="ckeck"]')
if check_req_elems is not None and check_elem is not None:
elem.remove(check_elem)
file.write('b.xml')
Example/Demo -
我的a.xml
-
<app>
<process>
<tag>any tag</tag>
<trigger order="3" name="activity1" perform="y">
<external>
<action name="check_req"/>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>>
<process>
<tag>any tag</tag>
<trigger order="2" name="activity1" perform="y">
<external>
<action name="event"/>
<action name="ckeck"/>
</external>
<var name="type"/>
<var name="user" />
</trigger>
</process>
</app>
代码-
>>> file = ET.parse('a.xml')
>>> root = file.getroot()
>>> for elem in root.findall('.//trigger/external'):
... check_req_elems = elem.find('.//action[@name="check_req"]')
... check_elem = elem.find('.//action[@name="ckeck"]')
... if check_req_elems is not None and check_elem is not None:
... elem.remove(check_elem)
...
>>> file.write('b.xml')
我的b.xml
变成-
<app>
<process>
<tag>any tag</tag>
<trigger name="activity1" order="3" perform="y">
<external>
<action name="check_req" />
<action name="event" />
</external>
<var name="type" />
<var name="user" />
</trigger>
</process>
<process>
<tag>any tag</tag>
<trigger name="activity1" order="2" perform="y">
<external>
<action name="event" />
<action name="ckeck" />
</external>
<var name="type" />
<var name="user" />
</trigger>
</process>
</app>
当两个动作在触发器中出现时,它们是否总是以相同的方式排序,即 "ckeck" 在 "ckeck_req" 之后并且相隔一行?如果是这种情况,您可以基于此给出条件,例如
action1 = "ckeck_req"
action2 = "ckeck"
with open(xmlfile, "r") as f:
x = f.readlines()
y = [] # new list without the unwanted actions
for i in range(len(x)):
if action2 in x[i] and action1 in x[i-2]:
continue
else:
y.append(x[i])
然后将新列表y写入文件。我只是在脑海中写下了这一点,所以很可能有更好的方法来做到这一点。现在我考虑了一下,您可能想看看 Regular Expressions.