ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用DTD验证XML无法使用lxml导入实体

2019-11-05 20:05:43  阅读:177  来源: 互联网

标签:lxml dtd xml python


我有一个生成NewsML类型XML文件的工具,我想在生成文件后对其进行验证.
我收到一个错误:

尝试加载网络实体http://www.w3.org/TR/ruby/xhtml-ruby-1.mod

python调用是:

parser = etree.XMLParser(load_dtd=True, dtd_validation=True)
treeObject = etree.parse(f, parser)

首先,我不确定是否同时需要“ load_dtd = True,dtd_validation = True”,但是无论如何我都在使用它.
第二个错误似乎来自定义为的导入的nitf-3-4.dtd:

<!ENTITY % xhtml-ruby.mod PUBLIC 
    "-//W3C//ELEMENTS XHTML Ruby 1.0//EN" "http://www.w3.org/TR/ruby/xhtml-ruby-1.mod">
%xhtml-ruby.mod;

lxml会出去检索此xhtml-ruby-1.mod还是我必须在本地拥有所有DTD文件.

解决方法:

尝试使用no_network = False构建解析器.如documentation中所述:

no_network – prevent network access when looking up external documents (on by default)

导入的dtd模块应该由lxml检索,但如果不允许网络访问,则将无法这样做(这对于文档本身而言并不重要,仅用于加载外部引用的文档.实际上,我希望您能够得到加载dtd本身时出错,因此我假设文档引用了该dtd的本地可用副本,并且仅dtd本身引用了远程资源?)

您还可以使用目录来使用本地可用的副本(不仅可以避免此问题,而且可以提高性能,并且对w3c服务器更友好;-)). Libxml2(由lxml使用)将检查/ etc / xml / catalog中是否存在目录以及XML_CATALOG_FILES环境变量(请参见Libxml2 docs)

(也可以为lxml编写自己的resolvers来拦截和处理请求,但是在这种情况下可能会过分杀伤)

请注意,除了解析时间验证外,还有另一个选择:使用DTD class分别加载dtd,并将​​其用作验证器.

这将使用提供的dtd验证解析的文档,而不管doctype声明引用了哪个dtd(如果有)(这很方便:并非每个有效的xml文件根据您想要的dtd都必须是有效的).

因为dtd只需要被检索和解析一次,所以如果您要验证很多文档,这应该会更快一些,并且(如果我没记错的话)您也不会遇到no_network问题.

这种方法的另一个好处是:您甚至可以在序列化元素/元素树之前验证它们(如果您的生产工具使用的是lxml).

最后一点:只有在解析时可以访问dtd才能解析某些文档(无法解析的实体…).如果可以,请避免这样做. (尽管并非所有人都同意:如果可能,请完全避免使用doctype声明).

标签:lxml,dtd,xml,python
来源: https://codeday.me/bug/20191105/1997541.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有