如何为具有出现约束的 XML 节点的无序列表创建模式 [英] How to create a schema for an unordered list of XML nodes, with occurrence constraints
问题描述
鉴于这样的 XML 布局,我正在尝试创建一个 XSD 架构来验证它.
Given an XML layout like this, I'm trying to create a XSD schema to validate it.
<RootNode>
<ChildA />
<ChildC />
<ChildB />
<ChildB />
<ChildA />
</RootNode>
要求如下:
- ChildA、ChildB 和 ChildC 可以以任何顺序出现.(
不合适) - ChildA 是强制性的,但可能会出现多次.
- ChildB 是可选的,可能会出现多次.
- ChildC 是可选的,可能只出现一次.
- ChildA, ChildB and ChildC may occur in any order. (
<xs:sequence>
unsuitable) - ChildA is mandatory but may occur multiple times.
- ChildB is optional and may occur multiple times.
- ChildC is optional and may occur once only.
我通常用来创建节点的无序列表的技术是对列表中的每个可能节点使用 <xs:choice maxOccurs="unbounded">
,但是,我是无法在 ChildA 上创建 minOccurs="1"
约束,在 ChildC 上创建 maxOccurs="1"
约束.(选择的出现次数优先于此处元素的出现次数).
The technique I usually use to create an unordered list of nodes is to use a <xs:choice maxOccurs="unbounded">
with each possible node in the list, however, I am unable to create the minOccurs="1"
constraint on ChildA and the maxOccurs="1"
contraint on ChildC. (The # of occurances of the choice takes precedence over those of the elements here).
<xs:element name="RootNode">
<xs:complexType>
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="ChildA" minOccurs="1"/>
<xs:element name="ChildB" />
<xs:element name="ChildC" maxOccurs="1"/>
</xs:choice>
</xs:complexType>
</xs:element>
推荐答案
更新:在 XSD 1.1m 中,对 all
组的一些限制已经解除.请在此处和此处查看答案.
Update: In XSD 1.1m some of the constraints on all
-groups have been lifted. See the answers here and here.
不是一个简单的但似乎可行的.这里的困难部分是模式定义必须是确定性的.我使用的方法是通过绘制问题的有限状态自动机来可视化问题,然后编写与该自动机对应的正则表达式.它并不像听起来那么复杂.不过,使用其他一些验证系统可能会提供更简单的答案.
Not a simple one but seems doable. Difficult part here is that Schema definitions must be deterministic. Approach I used was to visualize the problem by drawing a finite state automata of it and then to write a regular expression that corresponded that automata. It is not at all as complicated as it might sound. Still, using some other validation system would have likely provided simpler answer.
我已经做了一些测试,但很容易遗漏一些特殊情况.如果您发现错误,请发表评论.
I have done some testing but missing out some special cases is easy. Please comment if you spot an error.
...这是代码:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<!-- Schema for elements ChildA, ChildB and ChildC
The requirements are as follows:
* ChildA, ChildB and ChildC may occur in any order.
* ChildA is mandatory but may occur multiple times.
* ChildB is optional and may occur multiple times.
* ChildC is optional and may occur once only.
-->
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ABC-container" type="ABC" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="ABC">
<xsd:sequence>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
<xsd:choice>
<xsd:sequence maxOccurs="1">
<xsd:element name="ChildC" type="xsd:string"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="ChildA" type="xsd:string"/>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:sequence>
<xsd:sequence maxOccurs="1">
<xsd:element name="ChildA" type="xsd:string" minOccurs="1"/>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="ChildC" type="xsd:string"/>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
<xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:sequence>
</xsd:sequence>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
这篇关于如何为具有出现约束的 XML 节点的无序列表创建模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!