2014-11-22 2 views
1

Я пытаюсь удалить узлы в XML-файле. Мне удалось зайти так далеко, но когда скрипт запускается, он, кажется, берет атрибуты, принадлежащие родительскому элементу, который приходит после него.Как удалить XML-элементы без удаления содержимого из хвоста элементов?

Вот код:

for i, pid in enumerate(root.findall(".//p")): 
    for cont in pid.findall('membercontribution'): 
      for col in cont.findall('col'): 
       cont.remove(col) 


tree.write('fofo.xml') 

это:

<p id="S6CV0001P0-00507"><member>The Minister for Overseas Development (Mr. Neil Marten)   
</member><membercontribution>: a policy 
<col>16</col> 
foobar barforb </membercontribution></p> 

становится этим:

<p id="S6CV0001P0-00507"><member>The Minister for Overseas Development (Mr. Neil Marten)  
</member><membercontribution>: a policy </membercontribution></p> 

Как закодировать это так, что я получаю, чтобы сохранить «Foobar barforb "часть, которая приходит после?

ответ

1

Непреднамеренно удаляется здесь не атрибуты, а содержимое элемента tail.

Свойство tail является особенностью API ElementTree. Это текст сразу после конечного тега элемента и перед любым другим тегом. Когда вы удаляете элемент (в этом случае col), вы также удаляете его хвост.

Ясное объяснение, которое я нашел, это: http://infohost.nmt.edu/tcc/help/pubs/pylxml/web/etree-view.html.


Чтобы получить нужный вывод, что вам нужно сохранить ссылку на хвост удаленного col элемента и добавить его к тексту родительского элемента. Полный пример:

from xml.etree import ElementTree as ET 

XML = """ 
<root> 
<p id="S6CV0001P0-00507"><member>The Minister for Overseas Development (Mr. Neil Marten) 
</member><membercontribution>: a policy 
<col>16</col> 
foobar barforb </membercontribution></p> 
</root> 
""" 

root = ET.fromstring(XML) 

for pid in root.findall(".//p"): 
    for cont in pid.findall('membercontribution'): 
     for col in cont.findall('col'): 
      col_tail = col.tail.strip()   # Get the tail of "col" 
      cont.remove(col)      # Remove "col" 
      cont.text = cont.text.strip() + " " # Replace trailing whitespace with single space 
      cont.text = cont.text + col_tail  # Add the tail to "membercontribution" 

print ET.tostring(root) 

Выход:

<root> 
<p id="S6CV0001P0-00507"><member>The Minister for Overseas Development (Mr. Neil Marten) 
</member><membercontribution>: a policy foobar barforb</membercontribution></p> 
</root> 
+0

Спасибо за это. Есть ли способ удалить разрыв строки, который появляется между «политикой» и «foobar»? –

Смежные вопросы