XSD – 如何允许任何次数的任何顺序的元素?

我正在尝试创build一个XSD,并尝试写入具有以下要求的定义:

  • 允许指定的子元素出现任意次数(0为无界)
  • 允许子元素以任何顺序

我环顾四周,发现了像这样的各种解决scheme:

<xs:element name="foo"> <xsl:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="child1" type="xs:int"/> <xs:element name="child2" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> 

但从我的理解XS:select仍然只允许单个元素的select。 因此,像这样将MaxOccurs设置为无界应该只是意味着子元素的“任何一个”可以出现多次。 这是准确的吗?

如果上面的解决scheme是不正确的,我怎么能达到我上面在我的要求中所陈述的?

编辑 :如果要求如下?

  • 元素child1 child2可以出现任意次数(0表示无界)
  • 元素以任何顺序
  • 元素child3和child4应该只出现一次。

例如,这个XML是有效的:

 <foo> <child1> value </child1> <child1> value </child1> <child3> value </child3> <child2> value </child2> <child4> value </child4> <child1> value </child1> </foo> 

但这不(缺less孩子3)

 <foo> <child1> value </child1> <child1> value </child1> <child2> value </child2> <child4> value </child4> <child1> value </child1> </foo> 

在您的问题中的架构中, child1child2可以按任意顺序出现,任意次数。 所以这听起来像你在找什么。

编辑:如果你只想让其中的一个出现无限次数,那么无界将不得不继续使用这些元素:

编辑:修复XML中的types。

编辑:在maxOccurs大写O.

 <xs:element name="foo"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="child1" type="xs:int" maxOccurs="unbounded"/> <xs:element name="child2" type="xs:string" maxOccurs="unbounded"/> </xs:choice> </xs:complexType> </xs:element> 

如何在元素的子元素中指定一个名为child3 ,一个名为child4 ,以及任何名为child4child4数字,并且没有约束条件按照孩子出现的顺序。

这是一个可直接定义的常规语言,您需要的内容模型与定义一组正则expression式同构,该正则expression式定义数字“3”和“4”每个恰好出现一次,数字“1”和“2” '发生任何次数。 如果不明白怎么写这个,可能会帮助你考虑一下你将用什么样的有限状态机来识别这种语言。 它至less有四个不同的州:

  • 没有看到“3”和“4”的初始状态
  • 已经看到“3”但不是“4”的中间状态
  • 已经看到“4”但不是“3”的中间状态
  • “3”和“4”都已被看到的最终状态

无论自动机处于什么状态,都可以读取“1”和“2”。 他们不会改变机器的状态。 在初始状态下,“3”或“4”也将被接受。 在中间状态下,只接受“4”或“3” 在最后的状态下,“3”和“4”都不被接受。 正则expression式的结构最容易理解,如果我们首先为我们的语言的子集定义一个只有'3'和'4'的正则expression式:

 (34)|(43) 

要在给定位置允许“1”或“2”发生任何次数,如果我们的正则expression式语言接受这个符号,我们可以插入(1|2)* (或[12]* )。 插入这个expression式在所有可用的位置,我们得到

 (1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)* 

将其转换为内容模型非常简单。 基本结构相当于正则expression式(34)|(43)

 <xsd:complexType name="paul0"> <xsd:choice> <xsd:sequence> <xsd:element ref="child3"/> <xsd:element ref="child4"/> </xsd:sequence> <xsd:sequence> <xsd:element ref="child4"/> <xsd:element ref="child3"/> </xsd:sequence> </xsd:choice> </xsd:complexType> 

插入child1child2的零个或多个选项很简单:

 <xsd:complexType name="paul1"> <xsd:sequence> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="child1"/> <xsd:element ref="child2"/> </xsd:choice> <xsd:choice> <xsd:sequence> <xsd:element ref="child3"/> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="child1"/> <xsd:element ref="child2"/> </xsd:choice> <xsd:element ref="child4"/> </xsd:sequence> <xsd:sequence> <xsd:element ref="child4"/> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="child1"/> <xsd:element ref="child2"/> </xsd:choice> <xsd:element ref="child3"/> </xsd:sequence> </xsd:choice> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element ref="child1"/> <xsd:element ref="child2"/> </xsd:choice> </xsd:sequence> </xsd:complexType> 

如果我们希望尽量减less批量,我们可以为child1child2的重复select定义一个命名组:

 <xsd:group name="onetwo"> <xsd:choice> <xsd:element ref="child1"/> <xsd:element ref="child2"/> </xsd:choice> </xsd:group> <xsd:complexType name="paul2"> <xsd:sequence> <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/> <xsd:choice> <xsd:sequence> <xsd:element ref="child3"/> <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="child4"/> </xsd:sequence> <xsd:sequence> <xsd:element ref="child4"/> <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="child3"/> </xsd:sequence> </xsd:choice> <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> 

在XSD 1.1中, all组的一些限制已经被取消,因此可以更简洁地定义这个内容模型:

 <xsd:complexType name="paul3"> <xsd:all> <xsd:element ref="child1" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="child2" minOccurs="0" maxOccurs="unbounded"/> <xsd:element ref="child3"/> <xsd:element ref="child4"/> </xsd:all> </xsd:complexType> 

但从前面的例子可以看出,对all群体的这些变化实际上并没有改变语言的expression能力; 它们只是使某些种类的语言的定义更加简洁。

这是最后为我工作的:

 <xsd:element name="bar"> <xsd:complexType> <xsd:sequence> <!-- Permit any of these tags in any order in any number --> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element name="child1" type="xsd:string" /> <xsd:element name="child2" type="xsd:string" /> <xsd:element name="child3" type="xsd:string" /> </xsd:choice> </xsd:sequence> </xsd:complexType> </xsd:element> 

但从我的理解XS:select仍然只允许单个元素的select。 因此,像这样将MaxOccurs设置为无界应该只是意味着子元素的“任何一个”可以出现多次。 这是准确的吗?

maxOccurs="unbounded" 。对于由于maxOccurs="unbounded"而发生的xs:choice每个“重复”都会单独进行xs:choice 。 因此,你发布的代码是正确的,并且将实际上做你想要写的东西。

你应该发现下面的模式允许你提出的内容。

  <xs:element name="foo"> <xs:complexType> <xs:sequence minOccurs="0" maxOccurs="unbounded"> <xs:choice> <xs:element maxOccurs="unbounded" name="child1" type="xs:unsignedByte" /> <xs:element maxOccurs="unbounded" name="child2" type="xs:string" /> </xs:choice> </xs:sequence> </xs:complexType> </xs:element> 

这将允许您创build一个文件,如:

 <?xml version="1.0" encoding="utf-8" ?> <foo> <child1>2</child1> <child1>3</child1> <child2>test</child2> <child2>another-test</child2> </foo> 

这似乎符合你的问题。

如果以上都不起作用,那么您可能正在处理EDI trasaction,您需要根据HIPPA模式或任何其他复杂的xsd来validation您的结果。 要求是说,有8个REF段,其中任何一个都必须以任何顺序出现,也不是全部都是必需的,这意味着你可以按照以下顺序排列第一个REF,第三个REF,第二个REF,第九个REF。 在默认情况下,EDI接收将失败,因为默认的复杂types是

 <xs:sequence> <xs:element.../> </xs:sequence> 

当你通过refrence调用你的元素时,情况更加复杂,然后这个元素在它原来的位置本身就非常复杂。 例如:

 <xs:element> <xs:complexType> <xs:sequence> <element name="REF1" ref= "REF1_Mycustomelment" minOccurs="0" maxOccurs="1"> <element name="REF2" ref= "REF2_Mycustomelment" minOccurs="0" maxOccurs="1"> <element name="REF3" ref= "REF3_Mycustomelment" minOccurs="0" maxOccurs="1"> </xs:sequence> </xs:complexType> </xs:element> 

解:

这里简单地用“全部”replace“序列”或用最小/最大组合replace“select”将不起作用!

首先将"xs:sequence" with "<xs:all>"replace"xs:sequence" with "<xs:all>"现在,您需要对您所在的位置进行一些更改从中引用元素,然后转到:

 <xs:annotation> <xs:appinfo> <b:recordinfo structure="delimited" field.........Biztalk/2003"> 

***现在在上面的段中添加触发点,就像这样trigger_field =“REF01 _… complete name ..”trigger_value =“38”对于触发值不同的其他REF段,如“18” “,”XX“,”YY“等。因此,您的logging信息现在看起来像: b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">


这将使每个元素都是唯一的,理由是所有的REF段(上面的例子)具有相同的结构,如REF01,REF02,REF03。 在validation过程中,结构validation是可以的,但是它不会重复这些值,因为它会尝试在第一个REF本身中查找剩余的值。 添加触发器将使它们都是唯一的,它们将以任何顺序和情况通过(例如,使用5个9而不是全部9/9)。

希望它能帮助你,因为我花了近20个小时。

祝你好运