对于这样的XML布局,我尝试创建一个XSD模式来验证它。
<RootNode>
<ChildA />
<ChildC />
<ChildB />
<ChildB />
<ChildA />
</RootNode>
要求如下:
<xs:sequence>
我通常用来创建无序节点列表的技术是对列表中每个可能的节点使用<xs:choice maxOccurs="unbounded">
,但是,我无法在ChildA上创建minOccurs="1"
约束,在ChildC上创建maxOccurs="1"
约束。(选择的出现次数优先于此处元素的出现次数)。
<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>
发布于 2010-08-20 05:52:17
更新:在XSD1.1m中,对all
-groups的一些限制已经解除。请参阅答案here和here。
不是一个简单的方法,但似乎是可行的。这里的困难之处在于模式定义必须是确定性的。我使用的方法是通过绘制问题的有限状态自动机来可视化问题,然后编写与该自动机相对应的正则表达式。它并不像听起来那么复杂。尽管如此,使用其他验证系统可能会提供更简单的答案。
我已经做了一些测试,但忽略一些特殊情况是很容易的。如果您发现了错误,请发表意见。
...and代码如下:
<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>
发布于 2012-06-05 03:22:08
这应该会执行您指定的操作:
<xs:element name="RootNode">
<xs:complexType>
<xs:all>
<xs:element name="ChildA" minOccurs="1"/>
<xs:element name="ChildB" />
<xs:element name="ChildC" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>
</xs:element>
发布于 2012-01-26 06:34:27
我猜这将会被压缩成以下的relax-ng的紧凑语法:
head = element root { ChildA & ChildC? & ChildB* }
这真的很漂亮。
https://stackoverflow.com/questions/3382944
复制相似问题