想象一下,我有一个包含内容的文件test.html,
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Components of the SDK</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body></body></html>
在python提示符下执行此操作,
>>>import lxml.html
>>>t = lxml.html.parse('test.html')
>>>lxml.html.etree.tostring(t)
>>>'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n<?xml version="1.0" encoding="UTF-8" standalone="no"??><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Components of the SDK</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body/></html>'
注意在lxml读入数据然后再通过tostring将其打印出来后,doctype和xml标签是如何反转的?我们如何修复它以便它不会尝试修改文档(假设它已经很好地形成)。
答案 0 :(得分:6)
改为执行此操作(假设您的文档都是格式良好的XML)
etx = lxml.etree.parse('test.html')
print lxml.etree.tostring(etx, xml_declaration=True, encoding=etx.docinfo.encoding, standalone=etx.docinfo.standalone)
test.html
实际上并不是有效的HTML。它有空元素和xml处理指令。 html不理解这些。 html解析器将xml处理指令解释为SGML处理指令(这些指令类似于<? ... >
而不是xml <? ... ?>
),内容为xml version="1.0" encoding="UTF-8" standalone="no"?
。因此,当重新序列化为XML时,XML处理指令有两个问题,如:??>
使用html5lib
解析器或序列化程序的结果稍好一些 - 当重新序列化为XML时,处理指令将在注释中。这是因为HTML5也不允许使用SGML处理指令,并将xml前导码解释为要忽略的垃圾文本。
要获得所需的结果,请使用xml解析器(lxml.etree
)解析和序列化文档。它似乎是格式良好的xml和有效的XHTML1.1。如果您使用html序列化程序(lxml.html.tostring()
而非lxml.html.etree.tostring()
)进行序列化,则会输出一个多语言xhtml文档。
皱纹是序列化程序不会尝试完全保留xml声明(这毕竟不是xml信息集的一部分)。您必须将这些传递给tostring()
属性中的docinfo
方法。