如何删除以下xsd中的排序限制:
<xs:element name="example">
<xs:sequence>
<xs:element name="hostname" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="chunks" type="xs:string" minOccurs="1" maxOccurs="unbonded"/>
</xs:sequence>
</xs:element>
所以最后应该验证以下xml
<example>
<chunks>...</chunks>
<filename>...</filename>
<chunks>...</chunks>
</example>
<!-- -->
<example>
<filename>...</filename>
<chunks>...</chunks>
<chunks>...</chunks>
</example>
<!-- -->
<example>
<filename>...</filename>
<chunks>...</chunks>
<chunks>...</chunks>
<hostname>...</hostname>
</example>
接受的解决方案:
<xs:element name="example">
<xs:all>
<xs:element name="hostname" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="chunks" type="xs:string" minOccurs="1" maxOccurs="unbonded"/>
</xs:all>
</xs:element>
答案 0 :(得分:1)
你可以通过sequence
和choice
组合重复几种可能组合中的元素来实现这一目标,以保证所需的元素存在,但它赢了& #39;这么好又简单。我会建议一个不同的设计(如果可能的话)。
你的<chunks>
元素出现在任何地方有什么原因吗?如果您正在设计XML,那么决定实际需要哪些限制以及哪些限制应该变得灵活,这将简化生成和处理(以及验证)。将它们保存在序列中或包装它们将允许它们被视为group
并且将使验证更容易(它还将简化语言映射,例如,包装的相同元素经常被映射为数组)。
保持相似元素在一起的一种形式是sequence
,这是您不想要的。另一种方法是将其包装在一个类型中并使用xs:all
:
<xs:element name="example">
<xs:complexType>
<xs:all>
<xs:element name="filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="hostname" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="chunks" type="ChunksType" minOccurs="1" maxOccurs="1"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="ChunksType">
<xs:sequence>
<xs:element name="chunk" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
这会验证像这样的XML片段:
<example>
<chunks>
<chunk>...</chunk>
<chunk>...</chunk>
</chunks>
<filename>...</filename>
</example>
<!-- -->
<example>
<filename>...</filename>
<chunks>
<chunk>...</chunk>
<chunk>...</chunk>
</chunks>
</example>
<!-- -->
<example>
<filename>...</filename>
<chunks>
<chunk>...</chunk>
</chunks>
<hostname>...</hostname>
</example>
<example>
<hostname>...</hostname>
<filename>...</filename>
<chunks>
<chunk>...</chunk>
<chunk>...</chunk>
</chunks>
</example>
这些失败了:
<!-- missing filename -->
<example>
<chunks>
<chunk>...</chunk>
<chunk>...</chunk>
</chunks>
</example>
<!-- no chunks block -->
<example>
<filename>...</filename>
<hostname>...</hostname>
</example>
<!-- empty chunks block -->
<example>
<hostname>...</hostname>
<filename>...</filename>
<chunks></chunks>
</example>
您不能将unbounded
元素放在xs:all
中,因为它只允许0
或1
。您不能使用一系列选择,因为您有必需的元素。而且,您无法将xs:all
与sequence
结合起来解决您的问题(实际上您可以执行其中一些操作,但如果您使用的是XSD 1.1)。
在 XSD 1.1 中,您可以拥有xs:all
个unbounded
元素,因此您可以使用以下方式验证XML:
<xs:all>
<xs:element name="filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="hostname" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="chunks" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
</xs:all>
在XSD 1.0中是非法的。