Xsd 如何为无序列表创建一个模式,其中有些出现一次,有些出现多次
这是一个类似于的问题,但实际上稍微简单一点。然而,我很难理解序列和选择背后的逻辑(尤其是当它们嵌套在选择序列或选择序列中时),尽管我已经研究了很长时间,但我无法理解上面的例子是如何工作的Xsd 如何为无序列表创建一个模式,其中有些出现一次,有些出现多次,xsd,Xsd,这是一个类似于的问题,但实际上稍微简单一点。然而,我很难理解序列和选择背后的逻辑(尤其是当它们嵌套在选择序列或选择序列中时),尽管我已经研究了很长时间,但我无法理解上面的例子是如何工作的 我需要的是一个节点列表的模式,ChildA和ChildB,其中ChildA可以出现0-n次,但是ChildB只能出现0-1次。(实际上,我需要每种类型的几个节点,但是如果我可以为ChildA和ChildB做这件事,那么将它扩展到ChildX等和ChildY等应该很简单)。应该没有顺序约束。我非常感谢你的帮助。任
我需要的是一个节点列表的模式,ChildA和ChildB,其中ChildA可以出现0-n次,但是ChildB只能出现0-1次。(实际上,我需要每种类型的几个节点,但是如果我可以为ChildA和ChildB做这件事,那么将它扩展到ChildX等和ChildY等应该很简单)。应该没有顺序约束。我非常感谢你的帮助。任何深入解释模式指标的链接都会很有帮助。简短的回答是,在XSD 1.0中无法做到这一点;在XSD 1.1中,您可以使用
XSD:all
合成器(因为XSD 1.0中只有maxOccurs=1的限制已被删除)-然而,XSD 1.1的问题是:i)据我所知,它仅作为beta Xerces版本免费提供,目前;ii)有一个SAXON版本支持它,上次我看到它的引用时,你必须为此付费;iii)你将很难与其他人进行互操作,因为他们大多数仍然使用XSD 1.0
如果您可以使用Schematron——因为它只是XSLT1.0/2.0,所以肯定比XSD1.1更容易访问,那么编写它应该很容易,以便特定元素粒子的计数满足指定的标准;它将扩充一个XSD,其中合成器将是一个重复的XSD:choice
,其中选择选项是您允许的集合中的元素
有些人试图通过与正则表达式的构造进行并行来解释XSD合成器。如果您熟悉这一点,那么XSD1.0中的xsd:all
类似于方括号(虽然简单得多,没有范围或否定的概念),xsd:choice
类似于|(管道,交替),而xsd:sequence
则是其余部分(它关系到您编写内容的顺序)
我看到其他人也这么推荐。我自己没有试过,所以我把这个和免责声明一起传递给你。@Dave正在给ChildB添加一些愚蠢的属性,好吗?由于您对childB的要求是0-1,我们可以通过向childB添加一个固定属性并对该属性强制唯一约束来实现所需的解决方案
<complexType name="childAType">
<simpleContent>
<extension base="string"></extension>
</simpleContent>
</complexType>
<complexType name="childBType">
<simpleContent>
<extension base="string">
<attribute name="value" type="string" fixed="123"></attribute>
</extension>
</simpleContent>
</complexType>
<element name="root">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="childA" type="tns:childAType" minOccurs="0" maxOccurs="unbounded"></element>
<element name="childB" type="tns:childBType" minOccurs="0" maxOccurs="unbounded"></element>
</choice>
</complexType>
<unique name="childB.max.once">
<selector xpath="./tns:childB"></selector>
<field xpath="@value"></field>
</unique>
</element>
下面是一个有效的XML(B的顺序无关紧要,或者可以排除B)
然而,下面的一个是无效的
<tns:root xmlns:tns=" ">
<tns:childB></tns:childB>
<tns:childA></tns:childA>
<tns:childB></tns:childB>
<tns:childA></tns:childA>
<tns:childA></tns:childA>
</tns:root>
这将是我脑海中迅速想到的最简单的解决方案。这里的关键点是在“主”序列中使用另一个序列。通过将内部序列设置为从
开始,模式保持确定性;通过将该序列的基数设置为0-1,
保持可选
这是一个XMLSchema 1.0解决方案
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Schema for elements ChildA and ChildB
The requirements are as follows:
* ChildA and ChildB may occur in any order.
* ChildA is optional and may occur multiple times.
* ChildB is optional and may occur once only.
-->
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="AB-container" type="AB-type" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="AB-type">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="ChildA" type="xs:string" />
<xs:sequence minOccurs="0">
<xs:element name="ChildB" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="ChildA" type="xs:string" />
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:schema>
真可惜。根据我引用的线程:“通过组合和嵌套XMLSchema提供的各种组,并通过设置minOccurs和maxOccurs的值,可以表示任何可以用XML1.0表示的内容模型”。我希望Jasso会接受这个问题,因为他为更复杂的问题提供了解决方案。我会继续尝试。很抱歉延迟了,谢谢您的尝试,但如果我正确理解了这一点,ChildB节点将具有有效的“value”属性,这是我不想要的,因此它并不理想。我将继续尝试。@Dave XML实例不需要该属性,它只驻留在XML架构中。我也想不出其他的解决办法。XML不需要具有该属性,但如果它具有该属性,它将正确验证,这有点混乱。还是我还是误解了?贾索。非常抱歉,我应该为此感谢你。我必须继续做更重要的任务。我仍然没有机会好好看一看,但我将在回答时打勾,因为我们已经决定,毕竟我们不太担心订购限制,所以我可能永远没有机会真正解决它。很抱歉
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Schema for elements ChildA and ChildB
The requirements are as follows:
* ChildA and ChildB may occur in any order.
* ChildA is optional and may occur multiple times.
* ChildB is optional and may occur once only.
-->
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="AB-container" type="AB-type" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="AB-type">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="ChildA" type="xs:string" />
<xs:sequence minOccurs="0">
<xs:element name="ChildB" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="ChildA" type="xs:string" />
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:schema>