You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

lxml仅识别同一命名空间多导入XSD中的首个文件,求排查原因

问题描述

我使用lxml依据XSD Schema验证XML文件时遇到一个问题:当将btype.xsd导入同一命名空间时,lxml无法识别第二个导入的BType类型;但为btype.xsd设置单独命名空间时,验证可正常工作。

这套XSD在Apache Camel中即使同一命名空间多次导入也能正常工作,请问是lxml存在问题还是我的XSD编写有误?

相关XSD文件

main.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:bo="http://loremipsum.org/1/"
           targetNamespace="http://loremipsum.org/bi/1/"
           attributeFormDefault="unqualified" version="1.0">
    <xs:import namespace="http://loremipsum.org/1/" schemaLocation="../atype.xsd"/>
    <xs:import namespace="http://loremipsum.org/1/" schemaLocation="../btype.xsd"/>

    <xs:element name="batch">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="atype" type="bo:AType"> </xs:element>
                <xs:element name="btype" type="bo:BType"> </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

atype.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://loremipsum.org/1/"
           elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
    <xs:complexType name="AType">
        <xs:sequence>
            <xs:element name="ecm" type="xs:boolean" minOccurs="0">
            </xs:element>
            <xs:element name="type" type="xs:boolean" minOccurs="0">
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

btype.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://loremipsum.org/1/"
           elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
    <xs:complexType name="BType">
        <xs:sequence>
            <xs:element name="name" type="xs:string" minOccurs="0">
            </xs:element>
            <xs:element name="email" type="xs:string" minOccurs="0">
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
解答

你的XSD写法不符合W3C XML Schema规范。根据规范,同一个命名空间只能被导入一次——后续针对同一命名空间的<xs:import>会被处理器忽略。

Apache Camel能正常工作,是因为它使用的XSD处理器(如Apache Xerces)可能做了非标准扩展,允许合并同一命名空间的多个导入文件。但lxml依赖的libxml2遵循严格的规范,只会处理第一个针对该命名空间的导入,后续的btype.xsd不会被加载,自然无法识别BType类型。

正确解决方案

有两种规范内的解决方式:

  1. 合并文件:将AType和BType定义合并到同一个XSD文件中,在main.xsd里只导入一次该命名空间。
  2. 使用<xs:include>:因为atype.xsd和btype.xsd属于同一命名空间,在atype.xsd中用<xs:include>引入btype.xsd,然后main.xsd只保留对该命名空间的一次导入。

示例修改后的atype.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://loremipsum.org/1/"
           elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
    <xs:include schemaLocation="../btype.xsd"/>
    <xs:complexType name="AType">
        <xs:sequence>
            <xs:element name="ecm" type="xs:boolean" minOccurs="0">
            </xs:element>
            <xs:element name="type" type="xs:boolean" minOccurs="0">
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

同时将main.xsd中重复的<xs:import>删除,只保留一行:

<xs:import namespace="http://loremipsum.org/1/" schemaLocation="../atype.xsd"/>

内容的提问来源于stack exchange,提问作者Arunselvan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:55:57