Исправление tostring() в lxml Python

библиотека lxml это tostring() функция кажется довольно сломанной при печати только частей документов. Свидетель:

from lxml.html import fragment_fromstring, tostring
frag = fragment_fromstring('<p>This stuff is <em>really</em> great!')
em = frag.cssselect('em').pop(0)
print tostring(em)

я жду <em>really</em> но вместо этого он печатает <em>really</em> great! что это неправильно. Великий !- это не часть выбранного em. Это не только неправильно, это таблетка, по крайней мере, для обработки структурированного документа XML, где такой конечный текст будет общим.

как я понимаю, lxml хранит любой свободный текст, который приходит после текущий элемент в элементе . Сканирование кода на tostring() подводит меня к ElementTree.py s _write() функция, которая ясно всегда печатает хвост. Это правильное поведение для целых деревьев, но не для последнего элемента при рендеринге поддерева, но это не делает различия.

чтобы получить правильный хвостовой рендеринг выбранного XML, я попытался написать toxml() функция с нуля, чтобы использовать на своем месте. Это в основном сработало, но есть много особых случаев в обработке комментариев, инструкций по обработке, пространств имен, кодировок, yadda yadda. Поэтому я переключил передачу и теперь просто piggyback tostring(), постобработка его вывода для удаления нарушителя .tail текст:

def toxml(e):
    """ Replacement for lxml's tostring() method that doesn't add spurious
    tail text. """

    from lxml.etree import tostring
    xml = tostring(e)
    if e.tail:
        xml = xml[:-len(e.tail)]
    return xml

базовая серия тестов показывает, что это работает хорошо.

критика и/или предложения?

1 ответов


как о xml = lxml.etree.tostring(e, with_tail=False)?

from lxml.html import fragment_fromstring
from lxml.etree import tostring
frag = fragment_fromstring('<p>This stuff is <em>really</em> great!')
em = frag.cssselect('em').pop(0)
print tostring(em, with_tail=False)

выглядит так:with_tail был добавлен в v2.0; у вас есть более старая версия?