导入外部XSD的complexType且无需修改现有XML的方案咨询
问题根因
你抽离公共定义后出现验证失败,本质是命名空间不匹配:
common.xsd 声明了独立的目标命名空间http://test.com/common,其内部定义的testSubElement元素默认属于common命名空间。因此你在specific.xsd中直接引用common:testType作为根元素类型时,验证器会期望根元素的子元素是{http://test.com/common}testSubElement,但你的旧XML中testSubElement属于{http://test.com/specific}命名空间,两者不符导致校验失败。
可行解决方案
完全可以在不修改旧XML的前提下实现schema拆分,以下是两种常用方案:
方案1:使用变色龙(Chameleon)Schema设计(推荐)
这是改动最小的方案,核心是让公共schema没有目标命名空间,被业务schema引入时自动继承业务schema的命名空间,和你原本把定义写在specific.xsd里的效果完全一致。
操作步骤:
- 修改
common.xsd,移除targetNamespace属性和common默认命名空间声明:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.0"> <xs:complexType name="testType"> <xs:sequence> <xs:element name="testSubElement" type="testSubElement"></xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="testSubElement"></xs:complexType> </xs:schema>
- 修改
specific.xsd,把<import>改为<include>引入公共schema:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/specific" elementFormDefault="qualified" xmlns:specific="http://test.com/specific" version="1.0"> <include schemaLocation="common.xsd"/> <element name="testType" type="testType"></element> </schema>
修改完成后原XML不需要做任何改动,直接就能通过校验。
方案2:保留common独立命名空间的适配方案
如果你必须保留common.xsd的独立命名空间(比如其他业务需要直接使用common命名空间下的类型),可以在specific.xsd中重新定义适配旧XML的类型,仅复用common的类型定义:
修改后的specific.xsd如下:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/specific" elementFormDefault="qualified" xmlns:specific="http://test.com/specific" xmlns:common="http://test.com/common" version="1.0"> <import namespace="http://test.com/common" schemaLocation="common.xsd"/> <!-- 重新定义适配旧XML命名空间的testType --> <xs:complexType name="testType"> <xs:sequence> <!-- 元素属于specific命名空间,类型复用common的定义 --> <xs:element name="testSubElement" type="common:testSubElement"></xs:element> </xs:sequence> </xs:complexType> <element name="testType" type="specific:testType"></element> </schema>
该方案同样不需要修改旧XML即可完成校验,适合需要保留common命名空间独立性的场景。
内容的提问来源于stack exchange,提问作者lwestby
相关产品推荐
相关产品推荐

