如果我有扩展名,我怎样才能确保派生元素位于基类元素的前面?默认是相反的方式。我本来喜欢使用all
,但我知道这是不可能的。
<xs:complexType name="BaseClass">
<xs:sequence>
<xs:element name="foo" type="xs:string/>
<xs:element name="bar" type="xs:string/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="DerivedClass">
<xs:complexContent>
<xs:extension base="BaseClass">
<xs:sequence>
<!-- This makes the order foo, bar, cheese, tomato -->
<!-- But I need cheese, tomato, foo, bar -->
<xs:element name="cheese" type="xs:string/>
<xs:element name="tomato" type="xs:string/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="BaseClass" type="BaseClass"/>
<xs:element name="DerivedClass" type="DerivedClass" substitutionGroup="BaseClass"/>
我想接受的xml看起来像这样:
<mylist>
<BaseClass>
<foo>lala</foo>
<bar>lala</bar>
</BaseClass>
<DerivedClass>
<cheese>cheddar</cheese>
<tomato>red</tomato>
<foo>lala</foo>
<bar>lala</bar>
</DerivedClass>
</mylist>
目前我正在考虑将BaseClass
的所有元素复制到DerivedClass
中,但我不知道替换组会发生什么,不会发生什么。
答案 0 :(得分:7)
如果我有扩展名,我怎样才能确保派生元素位于基类元素的前面?
不幸的是,这是不可能的。 当扩展complexType时,新元素将作为序列添加到基本元素。 基本上,新的内容模型将如下所示:
(base element model), (extension element model)
这就是XSD中的类型扩展的工作原理。 你可能想知道为什么? 因为扩展类型必须符合基本类型。 你不能把任何东西作为基础的扩展。
假设您有一个知道如何处理A类元素的软件。 软件可以假设实际上可以扩展类型A, 但无论如何,它必须能够在一个假定为A类的元素中找到它 它知道/期望的所有类型A ...以及类型A固有的元素内容 (这是最重要的事情之一)必须是第一个!
答案 1 :(得分:0)
在验证由PHP生成的XML时遇到了同样的问题。
This就是我解决它的方式。基本上,
答案 2 :(得分:0)
解决此问题的唯一方法是使用组,可以将其插入序列中的任何位置。但是,使用这种方法无法使用substitutionGroup
。
<xs:group name="BaseGroup">
<xs:sequence>
<xs:element name="foo" type="xs:string"/>
<xs:element name="bar" type="xs:string"/>
</xs:sequence>
</xs:group>
<xs:complexType name="BaseClass">
<xs:group ref="BaseGroup"/>
</xs:complexType>
<xs:complexType name="DerivedClass">
<xs:sequence>
<xs:element name="cheese" type="xs:string"/>
<xs:element name="tomato" type="xs:string"/>
<xs:group ref="BaseGroup"/>
</xs:sequence>
</xs:complexType>
<xs:element name="BaseClass" type="BaseClass"/>
<xs:element name="DerivedClass" type="DerivedClass"/>