在不更改现有 XML 的情况下通过导入 XSD 在导入的 XSD 中使用复杂类型
Use complex types in imported XSD from importing XSD without changing existing XMLs
问题:是否可以将 complexTypes 导入模式而不必在生成的 XML 文件中声明两个名称空间?
我知道有人问过类似的问题,但是 none 我看到的已经涵盖了我的特定需求,这需要一些解释:
假设在某个软件的先前版本中,我们发布了一个类似于此示例的模式:
specific.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>
这样使用:
file.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>
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"/>
<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
我们是否可以将模式修改为这种 common/specific 模式,而无需更改符合模式的 XML 文件,同时保留验证?怎么做?
如果您想对两个模式文档中定义的元素使用相同的命名空间,那么两个模式文档应该有相同的目标命名空间,您应该使用 xs:include
而不是 xs:import
来组合它们.
问题:是否可以将 complexTypes 导入模式而不必在生成的 XML 文件中声明两个名称空间?
我知道有人问过类似的问题,但是 none 我看到的已经涵盖了我的特定需求,这需要一些解释:
假设在某个软件的先前版本中,我们发布了一个类似于此示例的模式:
specific.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>
这样使用:
file.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>
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"/>
<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
我们是否可以将模式修改为这种 common/specific 模式,而无需更改符合模式的 XML 文件,同时保留验证?怎么做?
如果您想对两个模式文档中定义的元素使用相同的命名空间,那么两个模式文档应该有相同的目标命名空间,您应该使用 xs:include
而不是 xs:import
来组合它们.