Python:检查XSD XML架构

2 投票
1 回答
3012 浏览
提问于 2025-04-15 22:04

我想在Python中查看一个XSD模式。目前我使用的是lxml库,它在验证文档是否符合模式时表现得非常好。但是,我想知道这个模式里面有什么,并且想在lxml的操作中访问这些元素。

这个模式是:

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:include schemaLocation="worker_remote_base.xsd"/>
    <xsd:include schemaLocation="transactions_worker_responses.xsd"/>
    <xsd:include schemaLocation="transactions_worker_requests.xsd"/>
</xsd:schema>

加载模式的lxml代码(简化版)是:

xsd_file_handle = open( self._xsd_file, 'rb')
xsd_text        = xsd_file_handle.read()
schema_document   = etree.fromstring(xsd_text, base_url=xmlpath)
xmlschema         = etree.XMLSchema(schema_document)

然后我可以使用schema_document(它是etree._Element)像处理XML文档一样遍历这个模式。但是,由于etree.fromstring(至少看起来是这样)需要一个XML文档,所以xsd:include元素没有被处理。

目前的问题是通过解析第一个模式文档来解决的,然后加载包含的元素,再一个一个手动插入到主文档中:

BASE_URL            = "/xml/"
schema_document     = etree.fromstring(xsd_text, base_url=BASE_URL)
tree                = schema_document.getroottree()

schemas             = []
for schemaChild in schema_document.iterchildren():
    if schemaChild.tag.endswith("include"):
        try:
            h = open (os.path.join(BASE_URL, schemaChild.get("schemaLocation")), "r")
            s = etree.fromstring(h.read(), base_url=BASE_URL)
            schemas.append(s)
        except Exception as ex:
            print "failed to load schema: %s" % ex
        finally:
            h.close()
        # remove the <xsd:include ...> element
        self._schema_document.remove(schemaChild)

for s in schemas:
# inside <schema>
    for sChild in s:
        schema_document.append(sChild)

我想要的是一个更常见的解决方案的想法。我已经搜索过其他的Python模式解析器,但到目前为止没有找到适合这个情况的。

问候,

1 个回答

0

PyXB 可以处理 xsd:include。这是一个很有用的工具,我在处理亚马逊网站的大型产品架构文件时用过它。这些文件中包含了多个层级的其他 xsd 文件。我非常推荐这个工具。

撰写回答