Краткий ответ
Сделайте это вместо этого (при условии, что все ваши документы имеют правильный формат 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()
), он выведет документ xgtml полиглота.
Складчатость заключается в том, что сериализатор не пытается точно сохранить объявление xml (этов конце концов, не является частью информационного набора xml).Вам нужно будет передать их методу tostring()
из свойства docinfo
.