Как удалить подузел из xml, которого нет в списке - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть xml с разным количеством уровней узлов. Я хочу проверить каждый узел в дереве и удалить его только тогда, когда он и его дочерние элементы отсутствуют в списке

<node1>
  <xxx>
     stuff
  </xxx>
  <subnode2>
     <yyy>
        stuf2
     </yyy>
  </subnode2>
</node1>

Моя проблема заключается в том, что если 'yyy' находится в списке dontRemove, а его родитель не так yyy все еще будет очищено.

import xml.etree.ElementTree as ET

document = ET.parse("foo.xml")
root = document.getroot()

#list of nodes
toRemove = root.findall('.//')

#list of tags that shouldn't be removed
dontRemove = ['xxx','yyy']

#take element from root and compare it with "dont remove it", if it's present remove from removing list
for element in list(toRemove):
    string = str(element)
    string = string.split(" ")
    string = string[1].replace("'", '')
    print(string)
    removed = 0
    for i in range(len(dontRemove)):
        if dontRemove[i] in string and removed == 0:
            toRemove.remove(element)
            removed = 1
#removing: 
for i in range(len(toRemove)):
    toRemove[i].clear()

1 Ответ

1 голос
/ 04 апреля 2020

Вы можете проверить, должен ли элемент удаляться периодически - если он содержит хотя бы одного «неустранимого» дочернего элемента, он не должен.

dontRemove = ['xxx','yyy']
elements_to_remove = []

def should_not_be_removed(parent):
    if parent.tag in dontRemove:
        return True

    nonremovable_child_found = False
    for child in parent:
        if should_not_be_removed(child):
            nonremovable_child_found = True
    if not nonremovable_child_found:
        elements_to_remove.append(parent)
    return nonremovable_child_found

should_not_be_removed(root)

После этого повторяющиеся вызовы, начинающиеся с root elements_to_remove, содержат список элементов, которые не содержат дочерний элемент с тегом, указанным в dont remove

Я также расширил ваш xml, чтобы охватить больше тестовых случаев, проверьте, что вы имели в виду:

<node1>
    <xxx>
        don't remove
    </xxx>
    <subnode2>
        <yyy>
            don't remove
        </yyy>
    </subnode2>
    <subnode3>
        remove
    </subnode3>
    <subnode4>
        <xxx>
            don't remove
        </xxx>
        <abc>
            remove
        </abc>
    </subnode4>
</node1>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...