lxml可通过启用DTD加载和验证实现XML对DTD的合规性检查,需设置XMLParser(dtd_validation=True, load_dtd=True, resolve_entities=False),并捕获etree.DocumentInvalid异常来判断验证是否失败。

lxml 不直接支持用 DTD 进行严格验证(比如 `xmlschema` 那样的纯模式校验),但它可以在解析时**启用 DTD 加载和验证**,并捕获是否符合 DTD 的错误。关键在于:必须显式开启 DTD 加载、设置解析器选项,并配合 `XMLParser` 使用。
1. 确保 DTD 文件可访问且被正确引用
XML 文件开头需有正确的 DOCTYPE 声明,例如:
其中 "note.dtd" 是相对路径(或绝对路径/URL)。lxml 默认不加载外部 DTD,所以你要确保该文件存在、路径正确,且没有网络阻断(如防火墙阻止远程 DTD)。
2. 创建带 DTD 支持的解析器
使用 etree.XMLParser(dtd_validation=True),并推荐关闭外部实体以提升安全性和稳定性:
立即学习“Python免费学习笔记(深入)”;
-
dtd_validation=True:启用 DTD 验证(默认为 False) -
load_dtd=True:允许加载外部 DTD(必需) -
resolve_entities=False:防止 XXE 攻击,同时避免因实体解析失败干扰验证
3. 解析并捕获验证错误
验证失败时,lxml 会抛出 etree.XMLSyntaxError(不是普通异常,而是子类 etree.DocumentInvalid)。建议用 try/except 捕获,并检查错误信息:
- 成功解析 → XML 符合 DTD
- 抛出
etree.DocumentInvalid→ DTD 验证失败(如元素缺失、属性非法、顺序错误等) - 抛出其他
XMLSyntaxError→ 可能是格式错误(如标签未闭合)、DTD 路径不对、编码问题等
4. 示例代码(简洁可用)
假设你有 data.xml 和同目录下的 note.dtd:
from lxml import etree
parser = etree.XMLParser(
dtd_validation=True,
load_dtd=True,
resolve_entities=False
)
try:
tree = etree.parse("data.xml", parser)
print("✅ XML 符合 DTD 规范")
except etree.DocumentInvalid as e:
print("❌ DTD 验证失败:", e)
except etree.XMLSyntaxError as e:
print("⚠️ 解析失败(可能 DTD 不可访问/格式错误):", e)
基本上就这些。注意:lxml 的 DTD 验证能力有限,不支持参数实体、条件节等高级特性;若需更严格的结构校验,建议转用 XSD + xmlschema 库。










