修复Python的lxml中的tostring()

Jon*_*ice 6 python xml lxml

tostring()当只打印部分文档时,lxml的功能似乎很破碎.见证人:

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)
Run Code Online (Sandbox Code Playgroud)

我希望<em>really</em>,而是它打印<em>really</em> great!这是错误的.最棒的 !' 是选定的一部分em.它不仅是错误的,它还是一种药丸,至少对于处理文档结构化的XML而言,这种结尾的文本很常见.

据我了解,lxml存储在元素.tail属性中当前元素之后的任何自由文本.扫描代码tostring()将我带到ElementTree.py的_write()函数,它显然总是打印尾部.这是整个树的正确行为,但在渲染子树时不是最后一个元素,但它没有区别.

为了获得所选XML的正确无尾渲染,我尝试toxml()从头开始编写一个函数来代替它.它基本上有效,但在处理注释,处理指令,命名空间,编码,yadda yadda时有许多特殊情况.所以我改变了方向,现在只需搭载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
Run Code Online (Sandbox Code Playgroud)

一系列基本测试表明这很有效.

批评和/或建议?

kin*_*all 12

怎么样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)
Run Code Online (Sandbox Code Playgroud)

看起来像是with_tail在v2.0中添加的; 你有旧版本吗?