【问题标题】:How to remove a child of child node using python element tree in xml file如何在 xml 文件中使用 python 元素树删除子节点的子节点
【发布时间】:2022-12-13 10:28:48
【问题描述】:

我是 xml 编码的初学者。我目前正在使用 Python 元素树进行编码。 我的 xml 文件如下所示

<net>
    <edge id=":1006232713_w0" function="walkingarea">
        <lane id=":1006232713_w0_0" index="0" allow="pedestrian" speed="1.00" />
        <lane id=":1006232713_w0_1" index="0" disallow="pedestrian" speed="1.00"/>      
    </edge>
    <edge id=":1006237429_0" function="internal">
        <lane id=":1006237429_0_0" index="0" allow="delivery bicycle" speed="5.69"/>
    </edge>
    <edge id=":1006237429_1" function="internal">
        <lane id=":1006237429_1_0" index="0" allow="pedestrian" speed="3.65"/>
    </edge>
    <edge id=":1006237429_w0" function="walkingarea">
        <lane id=":1006237429_w0_0" index="0" allow="pedestrian" speed="1.00"/>
        <lane id=":1006237429_w0_0" index="0" disallow="pedestrian" speed="5.50"/>
    </edge>
    <edge id=":1006249156_w0" function="walkingarea">
        <lane id=":1006249156_w0_0" index="0" allow="pedestrian" speed="1.00"/>
    </edge>
    <edge id=":1006249161_w0" function="walkingarea">
        <lane id=":1006249161_w0_0" index="0" disallow="pedestrian" speed="1.00"/>
    </edge>
        
</net>

在 xml 中,有子元素“edge”,edge 的子元素是“lane”要求:我想保留具有属性 allow="pedestrian" 的“车道”并删除另一条车道。 如果边缘下的车道没有 allow="pedestrian" 属性那么我想删除相应的边缘和车道

期望的输出

<net>

    <edge id=":1006232713_w0" function="walkingarea">
        <lane id=":1006232713_w0_0" index="0" allow="pedestrian" speed="1.00" />        
    </edge>

    <edge id=":1006237429_w0" function="walkingarea">
        <lane id=":1006237429_w0_0" index="0" allow="pedestrian" speed="1.00"/>
    </edge>
    <edge id=":1006249156_w0" function="walkingarea">
        <lane id=":1006249156_w0_0" index="0" allow="pedestrian" speed="1.00"/>
    </edge>
    
</net>

我尝试使用以下编码找到具有属性 allow="pedestrian" 的车道 ID

for edge in root.findall("./edge/lane/[@allow= 'pedestrian']..."):
    for lane in edge.find("./lane/[@allow= 'pedestrian']..."):
        print(lane.attrib['id'])

这会正确打印出边缘 ID,但会打印出边缘下方的车道 ID。 我只想选择边缘下具有属性 allow="pedestrian" 的车道并删除另一条车道。 如果边缘下的车道没有 allow="pedestrian" 属性那么我想删除相应的边缘和车道 如果有人能解决这个问题,那将非常有帮助。

【问题讨论】:

  • 您想要的输出仅显示 3 个 &lt;edge&gt; 元素;它不应该显示其中的 4 个吗?
  • @JackFleeting 感谢您的回复,是的,它应该显示 4 个边。我错过了在所需输出中添加边缘之一。下面的边缘也应该在所需的输出之下。 <edge id=":1006237429_1" function="internal"> <lane id=":1006237429_1_0" index="0" allow="pedestrian" speed="3.65"/> </edge>

标签: python xml elementtree


【解决方案1】:

我会使用 lxml 而不是 ElementTree,因为它对 xpath 的支持更好。

注意:答案假定实际文件结构与您的问题完全相同。如果不是,则答案可能无法按原样工作。

所以尝试这样的事情(虽然在你的情况下,你必须解析一个文件,而不是从下面的字符串加载):

from lxml import etree
nets = """[your xml above]"""
doc = etree.fromstring(nets)

for edge in doc.xpath('//edge'):
    target = edge.xpath('.//lane[@allow="pedestrian"]')
    if target:
        to_del=(target[0].xpath('following-sibling::lane'))
        if to_del:
            to_del[0].getparent().remove(to_del[0])
    else:
        edge.getparent().remove(edge)
print(etree.tostring(doc).decode())

输出应该是您的预期输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    相关资源
    最近更新 更多