首页 > 解决方案 > 在导入 XSD 中使用复杂类型,而不更改现有 XML

问题描述

问题:是否可以将 complexTypes 导入模式,而不必在生成的 XML 文件中声明两个名称空间?


我知道有人问过类似的问题,但我所见过的都没有涵盖我的具体需求,这需要一点解释:

假设在某个软件的早期版本中,我们发布了一个类似于以下示例的模式:

具体的.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/specific" xmlns="http://test.com/specific" 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>

    <element name="testType" type="common:testType"></element>
</xs:schema>

像这样使用:

文件.xml

<?xml version="1.0" encoding="UTF-8"?>
<testType xmlns="http://test.com/specific" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://test.com/specific specific.xsd">
    <testSubElement/>
</testType>

我们实际上有几个相似的模式,所以后来我们决定将通用定义提取到一个核心文件中,并将该文件导入相关的模式中:

common.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/common" xmlns="http://test.com/common" 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>

具体的.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"/>

    <element name="testType" type="common:testType"></element>
</schema>

但是,现在我们遇到了现有文件无法像以前那样正确验证的问题:

$ xmllint --schema specific.xsd myFile.xml
<?xml version="1.0" encoding="UTF-8"?>
<testType xmlns="http://test.com/specific" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://test.com/specific specific.xsd">
    <testSubElement/>
</testType>
myFile.xml:4: element testSubElement: Schemas validity error : Element '{http://test.com/specific}testSubElement': This element is not expected. Expected is ( {http://test.com/common}testSubElement ).
myFile.xml fails to validate 

我们是否可以将我们的模式修改为这种通用/特定模式,而无需更改符合模式的 XML 文件,同时保留验证?怎么做?

标签: xmlxsd

解决方案


如果您想为两个模式文档中定义的元素使用相同的命名空间,那么两个模式文档应该具有相同的目标命名空间,并且您应该使用xs:include而不是xs:import组合它们。


推荐阅读