使用复杂类型扩展的XML验证

时间:2015-03-21 17:18:59

标签: xml xsd

我的问题非常简单,我有第一个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

有没有解决方案?

1 个答案:

答案 0 :(得分:2)

你混淆了元素和类型。 root元素的定义要求它具有名为A的子元素(无名称空间或在thirdschema名称空间中,具体取决于第三个模式&#39; s elementFormDefault),但该元素的类型可以是b:B等子类型。所以它会验证

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

(使用a:A元素的基础{mythirdschema}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,那么您必须拥有全局元素声明以及各种模式中的类型声明并使用替代组:

第一个架构

<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>