使用Python从XML文件中删除不需要的元素

oo7oh9g9  于 2022-12-02  发布在  Python
关注(0)|答案(1)|浏览(133)

我正在用Python编写一个程序,使用一个API,它似乎不会根据用户是否被认为是活跃的来过滤请求。当我向API请求活跃用户的列表时,我得到了一个长得多的XML文档,看起来像下面的文本,它仍然包括<active>标记为假的用户。

<ArrayOfuser xmlns="WebsiteWhereDataComesFrom.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <user>
        <active>false</active>
        <datelastlogin>2/3/2014 10:21:13 PM</datelastlogin>
        <dept>0</dept>
        <email/>
        <firstname>userfirstname</firstname>
        <lastname>userlastname</lastname>
        <lastupdated/>
        <lastupdatedby/>
        <loginemail>userloginemail</loginemail>
        <phone1/>
        <phone2/>
        <rep>userinitials</rep>
    </user>
    <user>
        <active>true</active>
        <datelastlogin>8/21/2019 9:16:30 PM</datelastlogin>
        <dept>3</dept>
        <email>useremail</email>
        <firstname>userfirstname</firstname>
        <lastname>userlastname</lastname>
        <lastupdated>2/6/2019 11:10:29 PM</lastupdated>
        <lastupdatedby>userinitials</lastupdatedby>
        <loginemail>userloginemail</loginemail>
        <phone1>userphone</phone1>
        <phone2/>
        <rep>userinitials</rep>
    </user>
</ArrayOfuser>

程序最终需要返回一个仅来自活动用户的<rep>标记列表。
下面是我在开始这个项目时尝试的代码。我可能过于复杂了,因为我试图解析活动用户的users.xml,然后保存一个包含所有关于活动用户的XML数据的文件,然后在该文件中使用一个for循环从每个<rep>标签中获取信息,并将其保存到一个列表中:

to_remove = ['<active>false</active>']
with open('users.xml') as xmlfile, open('activeusers.xml','w') as newfile:
    for line in xmlfile:
        if not any(remo in line for remo in to_remove):
            newfile.write(line)

在activeusers.xml中,我希望看到下面的代码块。

<ArrayOfuser xmlns="WebsiteWhereDataComesFrom.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <user>
        <active>true</active>
        <datelastlogin>8/21/2019 9:16:30 PM</datelastlogin>
        <dept>3</dept>
        <email>useremail</email>
        <firstname>userfirstname</firstname>
        <lastname>userlastname</lastname>
        <lastupdated>2/6/2019 11:10:29 PM</lastupdated>
        <lastupdatedby>userinitials</lastupdatedby>
        <loginemail>userloginemail</loginemail>
        <phone1>userphone</phone1>
        <phone2/>
        <rep>userinitials</rep>
    </user>
</ArrayOfuser>

结果是用户xml文件的一个完全相同的副本,我的猜测是,如果程序复制了所有内容,那么它一定正确地阅读了该文件,但它绝对不会删除我需要的内容,因此语法一定不正确。这只是我想到的解决方案,程序不必创建一个名为activeusers.xml的新文件。最终的目标是只为活跃用户获取<rep>标记的列表,所以如果有更好的方法,我很想知道,因为我是一个完全的XML新手和Python新手。

shyt4zoc

shyt4zoc1#

既然你在处理xml,你应该使用一个合适的xml解析器,注意在这种情况下你也必须处理名称空间。
所以试试这个:

from lxml import etree
#load your file
doc = etree.parse("users.xml")
#declare namespaces
ns = {'xx': 'WebsiteWhereDataComesFrom.com'}

#locate your deletion targets
targets = doc.xpath('//xx:user[xx:active="false"]',namespaces=ns)
for target in targets:
    target.getparent().remove(target)

#save your file
with open("newfile.xml", 'a') as file:
    file.write(etree.tostring(doc).decode())

这应该会有您预期的输出。

相关问题