您当然可以扩展 XSD。你可以做很多事情。 XML Schema 允许您包含相同命名空间的 XSD、重新定义类型、导入不同命名空间的 XSD。
如果您有这样的 XML 实例:
<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="base.xsd">
<ORIGINAL_ELEMENT_1>aaa</ORIGINAL_ELEMENT_1>
<ORIGINAL_ELEMENT_2>bbb</ORIGINAL_ELEMENT_2>
</ROOT>
由此 XSD (base.xsd) 验证:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="ROOT" type="RootType"/>
<xs:complexType name="RootType">
<xs:sequence>
<xs:element name="ORIGINAL_ELEMENT_1" type="xs:string" minOccurs="0"/>
<xs:element name="ORIGINAL_ELEMENT_2" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
您需要扩展它以在ROOT 中添加两个新元素,您可以创建一个新模式,在其中重新定义元素的类型并声明新元素。例如,这个:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:redefine schemaLocation="base.xsd">
<xs:complexType name="RootType">
<xs:complexContent>
<xs:extension base="RootType">
<xs:sequence>
<xs:element ref="ELEMENT_ONE" minOccurs="0"/>
<xs:element ref="ELEMENT_TWO" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
<xs:element name="ELEMENT_ONE" type="xs:string"/>
<xs:element name="ELEMENT_TWO" type="xs:string"/>
</xs:schema>
将允许您将 ELEMENT_ONE 和 ELEMENT_TWO 添加到使用此 XSD (extended.xsd) 进行验证的文档中:
<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="extended.xsd">
<ORIGINAL_ELEMENT_1>aaa</ORIGINAL_ELEMENT_1>
<ORIGINAL_ELEMENT_2>bbb</ORIGINAL_ELEMENT_2>
<ELEMENT_ONE>xxx</ELEMENT_ONE>
<ELEMENT_TWO>yyy</ELEMENT_TWO>
</ROOT>
如果您有不同的命名空间,您可以使用xs:import 并重用类型定义和元素来创建新的类型、元素和属性。您还可以使用xs:include 将现有架构中的类型、元素和属性简单地添加到新架构中。
更新 - 关于内联 XSD
您询问了内联 XSD。它们是受支持的,但据我所知,这种支持是非标准(但我可能错了)。根据我的经验,我注意到虽然有些解析器在没有任何更改的情况下支持它们,但其他解析器会抱怨 xs:schema 不是最外层元素而失败,并且有些解析器会进行一些调整。
如果您的解析器支持它,它可能就像将 XSD 放在 ROOT 元素中一样简单:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:redefine schemaLocation="base.xsd">
<xs:complexType name="RootType">
<xs:complexContent>
<xs:extension base="RootType">
<xs:sequence>
<xs:element name="schema" namespace="http://www.w3.org/2001/XMLSchema"
processContents="skip" minOccurs="0" maxOccurs="1" />
<xs:element ref="ELEMENT_ONE" minOccurs="0"/>
<xs:element ref="ELEMENT_TWO" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
<xs:element name="ELEMENT_ONE" type="xs:string"/>
<xs:element name="ELEMENT_TWO" type="xs:string"/>
</xs:schema>
<ORIGINAL_ELEMENT_1>aaa</ORIGINAL_ELEMENT_1>
<ORIGINAL_ELEMENT_2>bbb</ORIGINAL_ELEMENT_2>
<ELEMENT_ONE>xxx</ELEMENT_ONE>
<ELEMENT_TWO>yyy</ELEMENT_TWO>
</ROOT>
这适用于 Microsoft 解析器和在线服务,例如 http://www.xmlvalidation.com。
某些基于 Apache XSV 的解析器可能找不到您的架构,除非您将 id='schemaName' 添加到您的 xs:schema 元素,然后使用属性 xsi:noNamespaceSchemaLocation="#schemaName" 从您的 ROOT 引用它。
解析器也可以尝试验证整个文档而不跳过xs:schema 块。如果发生这种情况,它会抱怨错位的xs:schema 元素。您可以解决这个问题,在您的 xs:sequence 中添加 xs:schema 元素的声明(如上面的代码所示)。