XML有一个父元素parent
,它必须包含10个子元素:child1
到child10
,但只有一次。
作为替代方案,parent
元素可以选择包含child11
到child20
,而不是child1
到child10
。
<parent><child1/><child4/> ... <child2/></parent> OK
<parent><child15/>...<child20/></parent> OK
<parent><child1/><child2/></parent> BAD, missing childs
<parent><child1/>...<child11/></parent> BAD: child11 shall never be with child1
<parent><child1/><child1/></parent> BAD: childs shall not be repeated
到目前为止,这是我的架构定义尝试:
<xs:complexType name="parent">
<xs:choice>
<xs:sequence>
<xs:element name="child1" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child2" type="xs:integer" minOccurs="1" maxOccurs="1"/>
...
</xs:sequence>
<xs:sequence>
<xs:element name="child11" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child12" type="xs:integer" minOccurs="1" maxOccurs="1"/>
...
</xs:sequence>
</xs:choice>
</xs:complexType>
答案 0 :(得分:2)
XML Schema 1.0没有直接解决您的问题。
您需要的是以下内容(将xs:sequence
替换为xs:all
),但这不是有效的XML架构语言:< / p>
<xs:complexType name="parent">
<xs:choice>
<xs:all>
<xs:element name="child1" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child2" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<!-- ... -->
</xs:all>
<xs:all>
<xs:element name="child11" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child12" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<!-- ... -->
</xs:all>
</xs:choice>
</xs:complexType>
问题在于xs:choice
允许xs:sequence
和xs:choice
合成器的嵌套,而不是xs:all
。
我看到有五种可能性:
xs:sequence
而不是xs:all
,但在验证之前使用XSL转换按架构重新排序。xs:assert
。xs:choice
定义为抽象类型,为两个内容模型选择定义派生类型,并使用parent
指定在XML文档中使用哪个类型。后两个选项都需要更改XML格式。
如果您可以为元素嵌套添加额外的级别,那么这就是您的架构的外观:
xsi:type
如果您使用类型替换,这就是您的架构的外观:
<xs:complexType name="option1">
<xs:all>
<xs:element name="child1" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child2" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<!-- ... -->
</xs:all>
</xs:complexType>
<xs:complexType name="option2">
<xs:all>
<xs:element name="child11" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child12" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<!-- ... -->
</xs:all>
</xs:complexType>
<xs:complexType name="parent">
<xs:choice>
<xs:element name="option1" type="option1"/>
<xs:element name="option2" type="option2"/>
</xs:choice>
</xs:complexType>
使用此方法的XML实例文档对于您的第一组元素看起来如下所示(请注意使用<xs:complexType name="parent" abstract="true">
</xs:complexType>
<xs:complexType name="parent_option1">
<xs:complexContent>
<xs:extension base="parent">
<xs:all>
<xs:element name="child1" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child2" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<!-- ... -->
</xs:all>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="parent_option2">
<xs:complexContent>
<xs:extension base="parent">
<xs:all>
<xs:element name="child11" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="child12" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<!-- ... -->
</xs:all>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="parent" type="parent"/>
指定已选择的组):
xsi:type
对于第二组:
<parent
xmlns="Your namespace here"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="parent_option1">
<child2>2</child2>
<child1>1</child1>
<!-- ... -->
</parent>