使用lxml解析DTD时出错

2 投票
1 回答
4013 浏览
提问于 2025-04-16 14:46

我正在尝试编写一个验证脚本,用来检查XML文件是否符合NITF DTD的标准,具体的标准可以在这个链接找到:http://www.iptc.org/std/NITF/3.4/specification/dtd/nitf-3-4.dtd。根据这篇帖子,我写了一个简单的脚本来验证NITF XML文档。但是,当我运行这个脚本时,出现的错误信息并不清楚,这让我很难找到问题所在。希望能得到一些帮助。

#!/usr/bin/env python


def main():
    from lxml import etree, objectify
    from StringIO import StringIO

    f = open('nitf_test.xml')
    xml_doc = f.read()
    f.close()

    f = open('nitf-3-4.dtd')
    dtd_doc = f.read()
    f.close()

    dtd = etree.DTD(StringIO(dtd_doc))
    tree = objectify.parse(StringIO(xml_doc))
    dtd.validate(tree)


if __name__ == '__main__':

    main()

错误追踪信息:

Traceback (most recent call last):
  File "./test_nitf_doc.py", line 23, in <module>
    main()
  File "./test_nitf_doc.py", line 16, in main
    dtd = etree.DTD(StringIO(dtd_doc))
  File "dtd.pxi", line 43, in lxml.etree.DTD.__init__ (src/lxml/lxml.etree.c:126056)
  File "dtd.pxi", line 117, in lxml.etree._parseDtdFromFilelike (src/lxml/lxml.etree.c:126727)
lxml.etree.DTDParseError: error parsing DTD

如果我把这一行:

dtd = etree.DTD(StringIO(dtd_doc))

改成:

dtd = etree.DTD(dtd_doc)

我得到的错误是:

lxml.etree.DTDParseError: failed to load external entity "NULL"

1 个回答

6

我查看了一下 nitf-3-4.dtd 文件,发现它引用了一个外部模块 xhtml-ruby-1.mod。你可以通过这个链接下载这个模块。这个模块需要放在当前目录下,这样 DTD 解析器才能加载它。

下面是一个完整的示例(假设你手头有一个有效的 NITF 文档):

% wget http://www.iptc.org/std/NITF/3.4/specification/dtd/nitf-3-4.dtd
% wget http://www.iptc.org/std/NITF/3.4/specification/dtd/xhtml-ruby-1.mod

Python 代码:

from lxml import etree, objectify
dtd = etree.DTD(open('nitf-3-4.dtd', 'rb'))
tree = objectify.parse(open('nitf_test.xml', 'rb'))
print dtd.validate(tree)

输出结果:

% python nitf_test.py
True

撰写回答