gpt4 book ai didi

python - 解析具有未定义实体的 XHTML5

转载 作者:行者123 更新时间:2023-11-30 23:22:20 25 4
gpt4 key购买 nike

请考虑这一点:

import xml.etree.ElementTree as ET

xhtml = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head><title>XHTML sample</title></head>
<body>
<p>&nbsp;Sample text</p>
</body>
</html>
'''
parser = ET.XMLParser()
parser.entity['nbsp'] = '&#x00A0;'
tree = ET.fromstring(xhtml, parser=parser)
print(ET.tostring(tree, method='xml'))

它呈现 xhtml 字符串的良好文本表示。

但是,对于具有 HTML5 文档类型的相同 XHTML 文档:

xhtml = '''<!DOCTYPE html>
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head><title>XHTML sample</title></head>
<body>
<p>&nbsp;Sample text</p>
</body>
</html>
'''

我得到异常:

xml.etree.ElementTree.ParseError:未定义实体:第 5 行,第 19 列

所以解析器无法处理它,尽管我将 nbsp 添加到实体字典中。

如果我使用lxml也会发生同样的情况:

from lxml import etree
parser = etree.XMLParser(resolve_entities=False)
tree = etree.fromstring(xhtml, parser=parser)
print etree.tostring(tree, method='xml')

加薪:

lxml.etree.XMLSyntaxError:实体“nbsp”未定义,第 5 行,第 26 列

尽管我已将解析器设置为忽略实体。

为什么会这样,以及如何使用 HTML5 doctype 声明解析 XHTML 文件?

<小时/>

lxml 的部分解决方案是使用恢复程序:

解析器= etree.XMLParser(resolve_entities=False,recover=True)

但我仍在等待更好的。

最佳答案

这里的问题是 Expat parser在幕后使用的通常不会报告未知实体 - 它会抛出错误,因此您尝试触发的 xml.etree.ElementTree 中的后备代码甚至不会运行。您可以使用 UseForeignDTD method要更改此行为,它将使 Expat 忽略 doctype 声明并将所有实体声明传递给 xml.etree.ElementTree。以下代码可以正确运行:

import xml.etree.ElementTree as ET

xhtml = '''<!DOCTYPE html>
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head><title>XHTML sample</title></head>
<body>
<p>&nbsp;Sample text</p>
</body>
</html>
'''
parser = ET.XMLParser()
parser._parser.UseForeignDTD(True)
parser.entity['nbsp'] = u'\u00A0'
tree = ET.fromstring(xhtml, parser=parser)
print(ET.tostring(tree, method='xml'))

这种方法的副作用:正如我所说,文档类型声明被完全忽略。这意味着您必须声明所有实体,甚至是文档类型所涵盖的实体。

请注意,您放入 ElementTree.XMLParser.entity 字典中的值必须是常规字符串,即实体将被替换的文本 - 您不能再引用其中的其他实体。所以   应该是 u'\u00A0'

关于python - 解析具有未定义实体的 XHTML5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24563300/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com