2015-06-26 1 views
0

Резюме: Имея следующий фрагмент в виде элемента ElementTree ...Как удалить элемент <text: soft-page-break /> из ElementTree?

<text:p>Text of the paragraph, <text:span>wrapped text</text:span> 
continuing <text:soft-page-break />and more of the text.</text:p> 

Как удалить эффективно в <text:soft-page-break /> элемент из структуры?

Детали: У меня есть content.xml файл, извлеченный из my.odt файла, сохраненного в формате OpenDocument в (от Microsoft Word). Моя цель - преобразовать его в формат AsciiDoc. Это означает распознавание важных частей и отбрасывание других частей.

Я использую xml.etree.ElementTree для анализа XML-файла в памяти. Поскольку у документа нет хорошей внутренней разметки (вы знаете, как пользователи используют инструменты WYSIWYG), преобразование предназначено для конкретного документа (книги).

Скажите, я хочу реализовать функцию, такую ​​как remove_empty_elements(root, 'text:soft-page-break', namespaces). Я знаю element.remove(subelement), который может удалить подэлемент из родительского элемента. Следующая реализация не является правильной:

def remove_empty_elements(root, tag, namespaces): 
    lst = [] 
    for parent in root.iterfind('.//' + tag + '/..', namespaces): 
     e = parent.find('./' + tag, namespaces) 
     if e.text is None: 
      lst.append((parent, e)) 

    for parent, e in lst: 
     parent.remove(e) 

Это не правильно, потому что and more of the text. часть принадлежит к удаленному элементу (как e.tail), и текст будет удален с элементом.

Как вы присоединитесь к тексту e.tail к хвосту предыдущего элемента? Или есть лучший подход?

ответ

1

Решение этой проблемы, относящейся только к documented API от xml.etree.ElementTree.

import xml.etree.ElementTree as ET 

sample = ''' 
<doc xmlns:text="http://example.com/"> 
    <text:p>Text of the paragraph, <text:span>wrapped text</text:span> 
    continuing <text:soft-page-break />and more of the text.</text:p> 
</doc> 
''' 

class MyTreeBuilder(ET.TreeBuilder): 

    def start(self, tag, attrib): 
     if not tag.endswith('soft-page-break'): 
      return super(MyTreeBuilder, self).start(tag, attrib) 

    def end(self, tag): 
     if not tag.endswith('soft-page-break'): 
      return super(MyTreeBuilder, self).end(tag) 

def my_fromstring(data): 
    parser = ET.XMLParser(target=MyTreeBuilder()) 
    parser.feed(data) 
    return parser.close() 

print ET.tostring(my_fromstring(sample)) 
+0

Спасибо Vasiliy. Я решил это по-другому - во время извлечения строки, но вещи в вашем ответе новы для меня и хорошо знают. Хорошо тебе провести время. – pepr