我需要一种方法来使用html5lib解析器生成一个真正的xml.etree.ElementTree。 (出于可移植性的原因,lxml不是一个选项。)
ELementTree.parse
can take a parser作为可选参数
xml.etree.ElementTree.parse(source, parser=None)
但目前尚不清楚这样的解析器会是什么样子。我可以在parser
参数中使用HTML5中的类或对象吗?关于这个问题的两个图书馆的文档都很薄。
上下文:
我的格式错误的XHTML文件无法使用ElementTree.parse
进行解析:
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Title</title></head>
<body><div class="cls">Note that this br<br>is missing a closing slash</div></body>
</html>
所以我使用html5lib.parse
代替了默认的treebuilder="etree"
参数,该参数运行正常。
但是html5lib显然没有输出xml.etree.ElementTree
对象,只有一个具有几乎相同的API。这有两个问题:
find
不支持namespaces
parameter,使得XPath过于冗长而没有笨拙的wrapper function。所以我不能单独使用ElementTree或html5lib。
答案 0 :(得分:2)
将xml.etree.ElementTree
视为etree
(因为它通常被导入):
返回的内容不是etree.ElementTree
,而是etree.Element
(这与etree.fromstring
返回的内容相同;只有etree.parse
返回etree.ElementTree
) 。它确实是etree模块的一部分 - 它不是具有类似API的东西。您遇到的问题与html5lib一样适用于etree.fromstring
。
Python documentation for xml.etree.ElementTree
没有提到namespaces
参数 - 它似乎是ElementTree
个对象(但不是Element
个对象)的未记录的特征。因此,它可能不是真正应该依赖的东西!您最好的选择可能是使用包装函数。
Eclipse不能通过树的事实可以归结为html5lib在存在时默认为xml.etree.cElementTree
这一事实 - 根据模块的文档,这是相同的,但是使用CPython的API在C中实现,阻止Eclipse的调试器运行。你可以使用非加速版本获得一个treebuilder(来自Python 3.3 的注释是C实现 - cElementTree
仅仅作为一个不推荐的别名存在),使用下面的代码:
import xml.etree.ElementTree as etree
import html5lib
tb = html5lib.getTreeBuilder("etree", implementation=etree)
p = html5lib.HTMLParser(tb)
tree = p.parse("<html>")
答案 1 :(得分:0)
您必须将回复包装在ElementTree
>>> from xml.etree.ElementTree import ElementTree
>>> from html5lib import parse
>>>
>>> ElementTree(parse("<html>"))
<xml.etree.ElementTree.ElementTree at 0x...>