使用Python和lxml来对外部DTD验证XML

2024-05-11 11:53:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图根据doctype标记中引用的外部DTD验证XML文件。具体来说:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">
...the rest of the document...

我使用的是python3.3和lxml模块。从阅读http://lxml.de/validation.html#validation-at-parse-time开始,我把这个组合起来:

^{pr2}$

据我所知验证.html,lxml库现在应该负责检索DTD并执行验证。但是,我得到的是:

$ ./mapwrangler.py validate notes.enex
Traceback (most recent call last):
  File "./mapwrangler.py", line 27, in <module>
    enexTree = etree.parse(enexFile, enexParser)
  File "lxml.etree.pyx", line 3239, in lxml.etree.parse (src/lxml/lxml.etree.c:69955)
  File "parser.pxi", line 1769, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:102257)
  File "parser.pxi", line 1789, in lxml.etree._parseFilelikeDocument (src/lxml/lxml.etree.c:102516)
  File "parser.pxi", line 1684, in lxml.etree._parseDocFromFilelike (src/lxml/lxml.etree.c:101442)
  File "parser.pxi", line 1134, in lxml.etree._BaseParser._parseDocFromFilelike (src/lxml/lxml.etree.c:97069)
  File "parser.pxi", line 582, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:91275)
  File "parser.pxi", line 683, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:92461)
  File "parser.pxi", line 622, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:91757)
lxml.etree.XMLSyntaxError: Validation failed: no DTD found !, line 3, column 43

这让我很惊讶,因为如果我关闭验证,那么文档就会很好地解析,我可以做print(enexTree.docinfo.doctype)来获得

$ ./mapwrangler.py validate notes.enex
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">

所以在我看来,找到DTD应该没有任何问题。在

谢谢你的帮助。在


Tags: inpysrchttpparserparselinexml
2条回答

出于一个我仍然不知道的原因,我的问题与XML目录在本地文件系统中的位置有关。在

在我的例子中,我使用了一个与组件内容管理系统(CCMS,在本例中是SDL trisoft2011 R2)紧密集成的XML编辑器。当编辑器连接到CCMS时,dtd、目录文件和一堆其他文件被同步。这些文件将在本地文件系统中结束:

C:\Users\[username]\AppData\Local\Trisoft\InfoShare Client\[id]\Config\DocTypes\catalog.xml

我不能让它发挥作用。只需将整个目录复制到另一个位置就可以解决问题,这样可以:

^{pr2}$

显然这并不理想,但它是有效的。在

可能是因为文件权限问题,还是因为Windows中的“文件路径太长”问题?我还没有尝试过符号链接是否有效。在

我使用的是Windows7、Python2.7.11和lxml的版本(3.6.0)。在

构造解析器对象时需要添加no_network=False。此选项默认设置为True。在

http://lxml.de/parsing.html#parsers上的解析器选项文档:

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

相关问题 更多 >