XML 使用复杂类型扩展进行验证

XML validation using complex type extension

我的问题很简单,我有第一个 XSD 架构,它定义了具有以下结构的类型:

<complexType name="A">
    <!-- attribute / element definition here -->
</complexType>

第一个模式属于命名空间 a。然后我有第二个模式,它也定义了另一种导入第一个的类型:

<complexType name="B">
    <complexContent>
        <extension base="a:A">
            <!-- attribute / element definition here -->
        </extension>
    </complexContent>
</complexType>

这次第二个模式属于 b 命名空间。一切正常,直到这里:我有第三个模式,它定义了这样的文档结构:

<element name="root">
    <sequence>
         <element name="A" type="a:A"></element>
    </sequence>
</element>

当我编写一个遵循此模式的 XML 文件时,它工作得很好,但我希望能够用 b:B 元素替换 a:A 元素,即:

<root xmlns="mythirdschema" xmlns:a="firstschema" xmlns:b="secondschema">
    <b:B>
        <!-- Attribute / element imposed by a:A definition -->
        <!-- Attribute / element imposed by b:B extension -->
    </b:B>
</root>

但它不起作用,当我尝试使用第三个模式验证我的 XML 文件时,它告诉我需要一个 a:A 元素, 而不是 b:B.

有什么解决办法吗?

您混淆了元素和类型。 root 元素的定义要求它有一个名为 A 的子元素(在没有名称空间或在 thirdschema 名称空间中,取决于第三个模式的 elementFormDefault),但是 [=该元素的 43=]type 可以是子类型,例如 b:B。所以它会验证

<root xmlns="mythirdschema" xmlns:a="firstschema" xmlns:b="secondschema">
    <A>
        <!-- Attribute / element imposed by a:A definition -->
    </A>
</root>

(对 {mythirdschema}A 元素使用基础 a:A 类型),或

<root xmlns="mythirdschema" xmlns:a="firstschema" xmlns:b="secondschema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <A xsi:type="b:B">
        <!-- Attribute / element imposed by a:A definition -->
        <!-- Attribute / element imposed by b:B extension -->
    </A>
</root>

(使用 b:B 子类型)。

如果您想更改元素名称而不是使用 xsi:type,那么您必须具有全局 element 声明以及各种模式中的类型声明并使用替换组:

第一个模式

<complexType name="A">
  <!-- attribute / element definition here -->
</complexType>

<element name="A" type="a:A" /><!-- assuming xmlns:a="firstschema" -->

第二个架构

<complexType name="B">
    <complexContent>
        <extension base="a:A">
            <!-- attribute / element definition here -->
        </extension>
    </complexContent>
</complexType>

<!-- assuming appropriate xmlns:a and xmlns:b -->
<element name="B" type="b:B" substitutionGroup="a:A" />

第三个模式

<element name="root">
    <sequence>
         <element ref="a:A"/>
    </sequence>
</element>

然后这将验证任一

<root xmlns="mythirdschema" xmlns:a="firstschema">
    <a:A>
        <!-- Attribute / element imposed by a:A definition -->
    </a:A>
</root>

(注意这里的 A 元素在第一个而不是第三个模式命名空间中),或者

<root xmlns="mythirdschema" xmlns:b="secondschema">
    <b:B>
        <!-- Attribute / element imposed by a:A definition -->
        <!-- Attribute / element imposed by b:B extension -->
    </b:B>
</root>