lxml序列化时缺少doctype

3 投票
2 回答
1410 浏览
提问于 2025-04-16 05:22
In [1]: from lxml import etree

我有一个HTML文档:

In [2]: root = etree.fromstring(u'''<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">\n<HTML></HTML>''', etree.HTMLParser())

它的文档类型(doctype)被正确解析了:

In [3]: root.getroottree().docinfo.doctype
Out[3]: u'<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN">'

但是在序列化的时候,我却丢失了它:

In [4]: etree.tostring(root.getroottree(), method='html')
Out[4]: '<html></html>'

我该怎么做才能把这个文档类型序列化出来呢?

我使用的是Debian GNU/Linux,版本是Sid。Python 2.6.6,lxml版本是2.2.8-2。

2 个回答

2

到目前为止,我唯一能让它正常工作的办法是使用默认的XML解析器,并在文档中添加一个非空的系统网址:

>>> html = etree.parse(StringIO('''<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN" " ">\n<HTML></HTML>'''))
>>> etree.tostring(html, method="xml")
'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN" " ">\n<HTML/>'
>>> etree.tostring(html, method="html")
'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN" " ">\n<HTML></HTML>'

而使用HTMLParser时,虽然得到的文档信息是一样的,但输出却不是我想要的结果:

>>> html = etree.parse(StringIO('''<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN" " ">\n<HTML></HTML>'''), etree.HTMLParser())
>>> etree.tostring(html, method="html")
'<html></html>'
1

有个问题,之前在另一个回答的评论里提到过:序列化时缺少文档类型。这个问题在2015年2月修复了,会在lxml的3.5版本中发布。

撰写回答