繁体   English   中英

如何根据条件使用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.ElementTreelxml

然后你可以使用XPath来查找所有的<external>下的元素<trigger> ,然后拿到action与name属性的元素check_reqaction元素与name属性为ckeck 然后,如果两者都不都不是,则意味着两个孩子都存在,请删除其名称属性为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')

示例/演示-

我的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_req”之后的“ ckeck”并且相隔一行? 如果是这种情况,您可以据此给出条件,例如

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写入文件。 我只是在脑海中写下了这一点,所以很可能有一种更好的方法可以做到这一点。 现在,我想一想,您可能要看一下正则表达式

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM