使用xs:extension忽略元素的顺序

时间:2010-04-22 09:25:14

标签: xml xsd

如何设计 xsd 以忽略元素序列?

<root> <a/> <b/> </root>

<root> <b/> <a/> </root>

出于代码生成原因,我需要使用extension,因此我使用all尝试了以下操作:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/test"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:t="http://www.example.com/test" >

    <xs:complexType name="BaseType">
        <xs:all>
            <xs:element name="a" type="xs:string" />
        </xs:all>
    </xs:complexType>

    <xs:complexType name="ExtendedType">
        <xs:complexContent>
            <xs:extension base="t:BaseType">
                <xs:all> <!-- ERROR -->
                    <xs:element name="b" type="xs:string" />
                </xs:all>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="root" type="t:ExtendedType"></xs:element>
</xs:schema>

此xsd无效,但<!-- ERROR -->报告了以下错误:

  

cos-all-limited.1.2:所有模型组必须出现在{min occurrence} = {max occurrence} = 1的粒子中,并且该粒子必须是构成{content type}的一对的一部分一个复杂的类型定义。

cos-all-limited.1.2的文档说:

  

1.2具有{max occurrence} = 1的粒子的{term}属性,它是构成复杂类型定义的{content type}的对的一部分。

我真的不明白这一点(既不是xsd也不是英语母语者:))。


我做错了什么,我做错了什么,或者没有办法实现这个目标?

3 个答案:

答案 0 :(得分:6)

MAJOR EDIT 最初我错过了您需要使用xsd:extension的要求。请注意,xsd:extension的工作方式与xsd:sequence一样,其中包含基类型的内容,后跟扩展类型的内容。正如XML Schema Primer所说:

  

当复杂类型派生时   扩展,其有效内容模型   是基类型的内容模型   加上指定的内容模型   类型推导。而且,   两个内容模型被视为两个   连续小组的孩子。

因此,似乎使这项工作的唯一方法是拥有一个空的基类型并将整个替代存储在扩展类型中,反之亦然(基础中的所有内容和空扩展)。像这样:

<xsd:complexType name="ExtendedType">
   <xsd:complexContent>
      <xsd:extension base="BaseType">
         <xsd:choice>
            <xsd:sequence>
               <xsd:element name="a" type="xsd:string"/>
               <xsd:element name="b" type="xsd:string"/>
            </xsd:sequence>
            <xsd:sequence>
               <xsd:element name="b" type="xsd:string"/>
               <xsd:element name="a" type="xsd:string"/>
            </xsd:sequence>
         </xsd:choice>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="BaseType"/>

<xsd:element name="root" type="ExtendedType"/>

答案 1 :(得分:6)

以下是限制的解释: http://marc.info/?l=xerces-j-user&m=118712527901786&w=4

使用“all”模型可以对复杂类型进行的唯一扩展是添加一些属性。您无法使用新元素进行扩展。

就我而言,我做过类似的事情:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/test"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:t="http://www.example.com/test" >

    <xs:complexType name="BaseType">
        <xs:all>
            <xs:element name="a" type="xs:string" />
        </xs:all>
    </xs:complexType>

    <xs:complexType name="ExtendedType">
        <xs:all>
            <xs:element name="a" type="xs:string" /> <!-- copy/paste from BaseType -->
            <xs:element name="b" type="xs:string" />
        </xs:all>
    </xs:complexType>

    <xs:element name="root" type="t:ExtendedType"></xs:element>
</xs:schema>

答案 2 :(得分:-3)

 

<xs:complexType name="BaseType"> 
    <xs:sequence> 
        <xs:element name="a" type="xs:string" /> 
    </xs:sequence> 
</xs:complexType> 

<xs:complexType name="ExtendedType"> 
    <xs:complexContent> 
        <xs:extension base="t:BaseType"> 
            <xs:sequence> 
                <xs:element name="b" type="xs:string" /> 
            </xs:sequence> 
        </xs:extension> 
    </xs:complexContent> 
</xs:complexType> 

<xs:element name="root" type="t:ExtendedType"></xs:element>