2

我需要的是一种使用 html5lib 解析器生成真正的 xml.etree.ElementTree 的方法。(出于可移植性的原因,lxml 不是一个选项。)

ELementTree.parse 可以将解析器作为可选参数

xml.etree.ElementTree.parse(source, parser=None)

但尚不清楚这样的解析器会是什么样子。HTML5 中是否有可以用于parser参数的类或对象?关于这个问题的两个库的文档都很薄。


上下文

我有一个无法解析的格式错误的 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 的对象。这有两个问题:

  • html5libfind不支持该namespaces参数,使得 XPath 过于冗长而没有笨拙的包装函数
  • Eclipse 调试器不支持对 html5lib etree 进行钻取。

所以我不能单独使用 ElementTree 或 html5lib。

4

2 回答 2

2

给定xml.etree.ElementTreeetree(因为它通常被导入为):

返回的不是一个etree.ElementTree,而是一个etree.Element(这与返回的相同etree.fromstring;只etree.parse返回一个etree.ElementTree)。它确实是 etree 模块的一部分——它不是具有类似 API 的东西。您遇到的问题etree.fromstring与 html5lib 一样适用。

的 Python文档xml.etree.ElementTree没有提到这个namespaces论点——它似乎是ElementTree对象(但不是Element对象)的一个未记录的特性。因此,它可能不是真正应该依赖的东西!您最好的选择可能是使用包装函数。

Eclipse 无法通过树的事实归结为 html5lib 默认为xml.etree.cElementTree它存在时的事实 - 根据模块的文档,这意味着相同,但使用 CPython 的 API 在 C 中实现,从而阻止 Eclipse 的调试器运行。您可以使用以下命令使用非加速版本(来自 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>")
于 2013-12-28T17:47:55.993 回答
0

您必须将响应包装在ElementTree

>>> from xml.etree.ElementTree import ElementTree
>>> from html5lib import parse
>>>
>>> ElementTree(parse("<html>"))
<xml.etree.ElementTree.ElementTree at 0x...>
于 2016-07-18T18:27:45.380 回答