BeautifulSoup 4是否解析外部DTD实体?

时间:2018-11-27 11:46:31

标签: python-3.x beautifulsoup lxml dtd tei

我有一个TEI文档,其中包含编码为&stern_1;的字符,它们映射到单独的Zeichen.dtd(文档类型定义)文件中。文件Zeichen.dtd包含以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY stern_1 "&#10035;" >

我正在使用BeautifulSoup4lxml-xml作为解析器。

示例:

dtd_str = '<!DOCTYPE Zeichen SYSTEM "Zeichen.dtd">'
xml_str = "<p>Hello, &stern_1;!</p>"
from bs4 import BeautifulSoup
soup = BeautifulSoup(dtd_str+xml_str, 'lxml-xml')
print(soup.find('p').get_text())

上面的代码显示:

 Hello, !

代替此:

 Hello, ✳!

我还尝试了内联DTD,结果相同:

dtd_str = """
<!DOCTYPE html [
    <!ENTITY stern_1 "&#10035;">
]>
"""
xml_str = "<p>Hello, &stern_1;!</p>"

from bs4 import BeautifulSoup
soup = BeautifulSoup(xml_str, 'lxml-xml')
print(soup.find('p').get_text())

输出:

Hello, !

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

最后找到了解决我自己问题的可行方法:

dtd_str = """
<!DOCTYPE html [
    <!ENTITY stern_1 "&#10035;">
]>
"""
xml_str = "<p>Hello, &stern_1;!</p>"
from lxml import etree
tree = etree.fromstring(dtd_str + xml_str)

from bs4 import BeautifulSoup
soup = BeautifulSoup(etree.tostring(tree, encoding='unicode'), "lxml-xml")
print(soup.find('p').get_text())

将打印以下内容:

Hello, ✳!

这正是我想要的。 lxml库可以正确处理dtd文件,而当您需要遍历树时,BeautifulSoup具有更好,更直观的API。