使用lxml删除带有文本的元素

bon*_*nzi 3 lxml

我有以下xml文件

<xml>
  <network id="5">
    <nodelist>
      <IP>10.10.0.135::3111</IP>
      <IP>10.10.0.130::3111</IP>
      <IP>10.10.0.129::3111</IP>
      <IP>10.10.0.129::3111</IP>
    </nodelist>
    <nodelist2/>
  </network>
</xml>
Run Code Online (Sandbox Code Playgroud)

我想删除IP 10.10.0.129的所有元素,其中network id = 5.我怎么能在lxml中做到这一点?

目前,我正在尝试使用xpath找到节点,我正在尝试删除它.

但,

netid=xml.xpath("network[@id=%s]/nodelist/IP[contains(text(),%s)]"%(id,node))
Run Code Online (Sandbox Code Playgroud)

给我错误lxml.etree.XPathEvalError: Invalid expression.

Sna*_*fee 5

我是一个python程序员,所以我用python 2.7编写它.如果你需要使用不同的语言,你必须自己移植它,因为我除了Python之外什么都不做.

注意,虽然这似乎处理xpath,但我的大多数处理都是用python完成的.

import lxml.etree as etree  #import etree, like c's include

def delete(xml,networkid,ipaddr):
    tree = etree.fromstring(xml)
    networks = tree.findall('.//network[@id="%s"]'%str(networkid)) #I think you forgot the quotes in your insertion.  
    for network in networks:  #for each network that has id='5'.
        ips = network.findall('.//IP') #All the IP elements under the network
        for ip in ips:  #iterating through a list of ips
            if ipaddr in ip.text:  #if ipaddr is inside the text, even if a port is appended
                ip.getparent().remove(ip)  #the ip's parent (nodelist) removes the ip element
return tree  # I give you the tree


s = r'''<xml>  #Here's your original xml
  <network id="5">
    <nodelist>
      <IP>10.10.0.135::3111</IP>
      <IP>10.10.0.130::3111</IP>
      <IP>10.10.0.129::3111</IP>
      <IP>10.10.0.129::3111</IP>
    </nodelist>
    <nodelist2/>
  </network>
</xml>'''

res = delete(s,'5','10.10.0.129')  #here's the result
print res  #and it's a tree.
print list(res.iter())  #so I print all the items under it.
print etree.tostring(res)  #and you have your edited xml.
Run Code Online (Sandbox Code Playgroud)