这里简要说明了基于XML的验证。我正在尝试解析一个引用嵌套DTD的XML文件:XML文件引用一个引用其他DTD的DTD。
我得到的错误是配置上的命名空间前缀SomeNameSpace未定义。我所要做的就是使用etree解析xml。parse是一个基于lxml的API。我的问题是
- 我可以只是关闭验证(我假设xml是正确的)?
- 我如何准确地为lxml提供所有嵌套的dtd,这样它就不会抱怨任何标记?
我看到过类似的问题,但是没有答案
一段时间后,我试图做类似的事情,未能找到解决方案。我最后编写了下面的脚本,它打开XML文件并使用正则表达式查找DTD。它还具有在命令行上采用DTD路径的重写,这是我的需求。
如果lxml处理嵌套dtd,那么下面的代码应该可以为您工作。
老实说,我觉得自己阅读文件有点麻烦,但这是我找到的唯一方法。
import re
import sys
import os.path
import codecs
from lxml import etree
def main(args):
if len(args)<1:
print("Not enough arguments given. Expected:")
print("tvalidatexml <xml file name> [<dtd file name>]n")
exit(1)
dtdRe = re.compile('.*<!DOCTYPE .* ["'](.*.dtd)["']>.*')
theDtd = None
inFile = args[0]
fdir = os.path.abspath(os.path.dirname(inFile))
if len(args)==2:
theDtd = os.path.abspath(args[1])
else:
with codecs.open(args[0], 'r', 'utf-8') as inf:
for ln in inf:
mtch = dtdRe.match(ln)
if mtch:
if os.path.isabs(mtch.group(1)):
theDtd = mtch.group(1)
else:
theDtd = os.path.abspath(fdir + '/' + mtch.group(1))
break
if theDtd is None:
print("No DTD specified!")
exit(2)
if not os.path.exists(theDtd):
print("The DTD ({}) does not exist!".format(theDtd))
exit(3)
print('Using DTD:', theDtd)
parser = etree.XMLParser(dtd_validation=True)
dtd = etree.DTD(open(theDtd))
tree = etree.parse(args[0])
valid = dtd.validate(tree)
if (valid):
print("XML was valid!")
else:
print("XML was not valid:")
print(dtd.error_log.filter_from_errors())
if __name__ == '__main__':
main(sys.argv[1:])
你可以尝试用Beautiful Soup解析吗?错误还存在吗?