【问题标题】:python lxml: import XSD from a buffer?python lxml:从缓冲区导入 XSD?
【发布时间】:2014-12-08 07:16:15
【问题描述】:

我正在使用 Python 中的 LXML 来验证具有匹配 XSD 的 XML。
该 XSD 导入了第二个“通用”XSD,其中包括一些通用定义。
问题是这些 XSD 在本地不作为文件存在。它们只是我保存在内存中的缓冲区,但是当 XSD 执行 <import><redefine> 时,它会在文件系统的当前目录中查找导入的文件。

有没有办法让它不这样做?可以提前提供进口的XSD?

LXML 使用 libxml2 和 libxslt 进行解析。
导入的 XSD 文件的打开源于 libxml2 代码的深处,并且不经过 python 的文件处理,因此仅覆盖 open() 是行不通的。似乎 libxml2 也没有任何工具可以为其提供文件解析器。它只是直接调用fopen()

所以解决方案可能需要在更高级别,可能覆盖命名空间或类似的东西?

【问题讨论】:

    标签: python xml xsd lxml


    【解决方案1】:

    与其通过open()/fopen() 覆盖或更改源名称空间来解决问题,不如考虑使用XML 目录自定义URI 解析器

    XML Catalogs让你控制:

    1. 将外部实体的公共标识符和/或系统标识符映射到 URI 引用。
    2. 将资源的 URI 引用(命名空间名称、样式表、图像等)映射到另一个 URI 引用。

    您可以阅读如何将 XML 目录与 libxml2 here 一起使用。

    虽然 XML 目录不直接支持基于内存的 XSD,但您可能能够找到比较低级别的 open()/fopen() 方法更好的覆盖方法。

    然而,一个更有希望的方法可能是编写一个自定义 URI 解析器。一个示例自定义 URI 解析器是 provided in the lxml documentation:

    >>> from lxml import etree
    
    >>> class DTDResolver(etree.Resolver):
    ...     def resolve(self, url, id, context):
    ...         print("Resolving URL '%s'" % url)
    ...         return self.resolve_string(
    ...             '<!ENTITY myentity "[resolved text: %s]">' % url, context)
    

    【讨论】:

    • 我将&lt;redefine&gt;schemaLocation 属性设置为http://example.com/sPakcageCommon.xsd,但我的解析器从未被调用,我得到“无法解析XML 资源”
    • 可能是添加了详细信息的新问题的候选者,但我首先要确定问题是否特定于 xsd:redefine,或者您的解析器是否根本没有被调用以获得任何解决方案。
    • 问题是我的解析器抛出异常。 lxml 默默地吞下异常并移至默认解析器。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多