繁体   English   中英

来自StringIO源的Python xml etree DTD?

[英]Python xml etree DTD from a StringIO source?

我正在调整以下代码(通过这个问题中的建议创建),它接受了一个XML文件并且它是DTD并将它们转换为不同的格式。 对于这个问题,只有加载部分很重要:

xmldoc = open(filename)

parser = etree.XMLParser(dtd_validation=True, load_dtd=True)    
tree = etree.parse(xmldoc, parser)

这在使用文件系统时运行良好,但我将其转换为通过Web框架运行,其中两个文件通过表单加载。

加载xml文件工作正常:

tree = etree.parse(StringIO(data['xml_file']) 

但是,当DTD链接到xml文件的顶部时,以下语句将失败:

parser = etree.XMLParser(dtd_validation=True, load_dtd=True)
tree = etree.parse(StringIO(data['xml_file'], parser)

通过这个问题 ,我试过:

etree.DTD(StringIO(data['dtd_file'])
tree = etree.parse(StringIO(data['xml_file'])

虽然第一行不会导致错误,但第二行会出现在DTD意图拾取的unicode实体上(并且在文件系统版本中这样做):

XMLSyntaxError:实体'eacute'未定义,第4495行,第46列

如何正确加载此DTD​​?

这是一个简短而完整的例子,使用@Steven提到的自定义解析器技术。

from StringIO import StringIO
from lxml import etree

data = dict(
    xml_file = '''<?xml version="1.0"?>
<!DOCTYPE x SYSTEM "a.dtd">
<x><y>&eacute;zz</y></x>
''',
    dtd_file = '''<!ENTITY eacute "&#233;">
<!ELEMENT x (y)>
<!ELEMENT y (#PCDATA)>
''')

class DTDResolver(etree.Resolver):
     def resolve(self, url, id, context):
         return self.resolve_string(data['dtd_file'], context)

xmldoc = StringIO(data['xml_file'])
parser = etree.XMLParser(dtd_validation=True, load_dtd=True)
parser.resolvers.add(DTDResolver())
try:
    tree = etree.parse(xmldoc, parser)
except etree.XMLSyntaxError as e:
    # handle xml and validation errors

您可以使用自定义解析器 文档实际上给出了一个提供dtd的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM