如何使用lxml同时验证XML与XSD文件和内联模式?

2 投票
1 回答
6464 浏览
提问于 2025-04-17 07:56

我在用lxml验证一些xml文件时遇到了问题。XSD模式和XML文件都是来自亚马逊的文档,所以应该是兼容的。但是,XML文件本身引用了另一个没有被加载的模式。

这是我的代码,基于lxml验证教程

xsd_doc = etree.parse('ProductImage.xsd')
xsd = etree.XMLSchema(xsd_doc)
xml = etree.parse('ProductImage_sample.xml')
xsd.validate(xml)
print xsd.error_log

我收到的错误信息是:“ProductImage_sample.xml:2:0:错误:SCHEMASV:SCHEMAV_CVC_ELT_1: 元素 'AmazonEnvelope': 没有可用的全局声明来验证根元素。”

如果我用amzn-envelope.xsd来验证,而不是ProductImage.xsd,就不会出现错误,但这就失去了验证特定图像数据是否有效的意义。顺便说一下,所有提到的xsd和xml文件都在我的工作目录里,还有我的python脚本。

这是一个示例xml的片段,应该是有效的:

<?xml version="1.0"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
    <Header>
        <DocumentVersion>1.01</DocumentVersion>
        <MerchantIdentifier>Q_M_STORE_123</MerchantIdentifier>
    </Header>
    <MessageType>ProductImage</MessageType>
    <Message>
        <MessageID>1</MessageID>
        <OperationType>Update</OperationType>
        <ProductImage>
            <SKU>1234</SKU>

这是模式的一个片段(这个文件不是公开的,所以我不能展示全部内容):

<?xml version="1.0"?>
<!-- Revision="$Revision: #5 $" -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xsd:include schemaLocation="amzn-base.xsd"/>
    <xsd:element name="ProductImage">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="SKU"/>

我可以说,跟随amzn-base.xsd的引用并没有找到AmazonEnvelope标签的定义。所以我的问题是:lxml能否通过像<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">这样的标签来加载模式?如果不能,我该如何验证我的图像数据?

1 个回答

2

答案是我应该通过父级的模式文件来进行验证,正如在XML文件顶部提到的,那个文件叫做amzn-envelope.xsd,因为它包含了以下内容:

<xsd:include schemaLocation="ProductImage.xsd"/>

一般来说,lxml不会读取像xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"这样的声明,但如果你能找到父级的模式文件来进行验证,那么这个文件应该能包含你感兴趣的具体模式。

撰写回答