Xsd 这些元素中至少有一个,但有些元素最多只有一个
我希望我的XSD能够强制一组元素中至少有一个必须存在。有些元素可以无限次出现,有些是有限的 这些元素本身都不是强制性的,但必须至少有一个元素存在 最后,元素可以以任何顺序出现。i、 e.该命令不得强制执行,也不得对文件的处理产生任何影响 我的尝试是:Xsd 这些元素中至少有一个,但有些元素最多只有一个,xsd,Xsd,我希望我的XSD能够强制一组元素中至少有一个必须存在。有些元素可以无限次出现,有些是有限的 这些元素本身都不是强制性的,但必须至少有一个元素存在 最后,元素可以以任何顺序出现。i、 e.该命令不得强制执行,也不得对文件的处理产生任何影响 我的尝试是: <xs:element name="Root"> <xs:complexType> <xs:choice> <xs:element minOccurs="0" maxOccurs="
<xs:element name="Root">
<xs:complexType>
<xs:choice>
<xs:element minOccurs="0" maxOccurs="unbounded" name="A" type="a:a"/>
<xs:element minOccurs="0" maxOccurs="unbounded" name="B" type="a:a"/>
<xs:element minOccurs="0" maxOccurs="1" name="C" type="a:a"/>
<xs:element minOccurs="0" maxOccurs="1" name="D" type="a:a"/>
</xs:choice>
</xs:complexType>
</xs:element>
这不太有效,因为它不强制至少存在其中一个元素
因此,在上面的例子中,必须至少有A、B、C或D中的一个。
可以有多个A或B元素,但每个C或D元素只能有一个
因此,以下各项均应有效:
-必须至少存在一个元素
-必须至少存在一个元素
-重复
元素
我还尝试过同时使用xs:choice(子元素中没有minOccurs)和xs:sequence(没有C&D节点),但我找不到任何允许两者共存的父元素。除了允许前两个示例之外,应该是无效的,您显示的内容模型也失败了,因为它不允许使用第三个或第五个应ok示例 到目前为止,捕获您在XSD、RELAXNG或DTD中描述的约束的最简单方法是添加另一个约束并约束顺序。然后,内容模型是(用DTD表示法)
((A+,B*,C?,D)|(B+,C?,D?)|(C,D?)|(D))
。如果A、B、C、D子项的顺序不传递任何信息,这是迄今为止最简单的方法
然而,如果孩子们的顺序确实传达了信息,并且需要自由,那么你就有一个最复杂的任务。不是特别难,但很复杂,有时(特别是对于更复杂的例子)相当乏味
您描述的A、B、C和D儿童的合法序列集是一种常规语言;考虑一下你用来识别它的有限状态自动机可能会有所帮助。基本上,您需要跟踪三位信息:(a)我们是否看到任何子元素?(b) 我们见过C元素吗?(c) 我们见过D元素吗?如果这些是完全独立的,我们需要在FSA中有八个州;因为它们不是,我们只需要五个:
- 0开始状态(否、否、否)
- 1已看到一个或多个A或B元素,但未看到C或D(是、否、否)
- 2已经看到一个C元素,没有D(X,是,否)
- 3已经看到了D元素,没有C元素
- 4.我见过C和D
- 0a,B->1;C->2;D->3
- 1 A,B->1;C->2;D->3
- 2 A,B->2;C->错误;D->4
- 3 A,B->3;C->4;D->错误
- 4a,B->4;C、 D->错误
((A|B)+, ( (C, (A|B)*, (D, (A|B)*)?)
| (D, (A|B)*, (C, (A|B)*)?) )? )
把这些放在一起,内容模型作为一个整体就变得
( ( (A|B)+, ( (C, (A|B)*, (D, (A|B)*)?)
| (D, (A|B)*, (C, (A|B)*)?) )? )
| (C, (A|B)*, (D, (A|B)*)?)
| (D, (A|B)*, (C, (A|B)*)?) )
将其转换为XSD符号很简单
在一些模式语言中,有更方便的(大多数人的意思是:更紧凑)方式来表达这个或相关的内容模型
在Schematron或XSD1.1中,您可以编写断言(使用XPath)来表示
- 每个孩子都被命名为A、B、C或D
- 至少有一个孩子
- 最多有一个名为C的孩子
- 最多有一个名为D的孩子
(A* & B* & C? & D?)
您可以使用稍微复杂一点的模型强制非空性:
( ((A|B), (A* & B* & C? & D?))
| (C, (A* & B* & D?))
| (D, (A* & B* & C?)) )
哇!谢谢你非常详细的回答。不幸的是,我不熟悉DTD语法,但是如果我假设它有点类似于正则表达式,那么我可以理解这里的内容。只是想澄清一点——在我的例子中,元素的顺序是完全不相关的。订单不应受到任何限制,也不应以任何方式影响文档的处理。父元素本质上是一个混杂的包,它考虑了用所有可能的顺序复制该组的想法。然而,对于4种元素类型来说,这是非常困难的——在我的实际示例中,实际上有5种元素类型,这几乎肯定会增加。因此,这不是一个实用的解决方案-一定需要更通用的解决方案!是的,DTD表示法类似于(常规正则表达式的子集),只是用逗号而不是并置来描述序列
(A* & B* & C? & D?)
( ((A|B), (A* & B* & C? & D?))
| (C, (A* & B* & D?))
| (D, (A* & B* & C?)) )