xml XSD - 如何以任意顺序允许任意次数的元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2290360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 12:59:28  来源:igfitidea点击:

XSD - how to allow elements in any order any number of times?

xmlxsd

提问by jvtech

I am trying to create an XSD, and trying to write the definition with the following requirement:

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

  • Allow child element specified to appear any number of times (0 to unbounded)
  • Allow child elements to be in any order
  • 允许指定的子元素出现任意次数(0 到无界)
  • 允许子元素按任何顺序排列

I looked around and found various solutions like this:

我环顾四周,发现像各种解决方案这样

<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>

But from what I understand xs:choice still only allows single element selection. Hence setting the MaxOccurs to unbounded like this should only mean that "any one" of the child elements can appear multiple times. Is this accurate?

但据我了解 xs:choice 仍然只允许单元素选择。因此,像这样将 MaxOccurs 设置为 unbounded 应该只意味着“任何一个”子元素可以出现多次。这是准确的吗?

If above solution is incorrect, how can I achieve what I stated above in my requirement?

如果上述解决方案不正确,我如何才能实现我在我的要求中所述的内容?

EDIT: What if the requirement is as follows?

编辑:如果要求如下怎么办?

  • Element child1 child2 can appear any number of times (0 to unbounded)
  • Elements to be in any order
  • Elements child3 and child4 should appear exactly once.
  • 元素 child1 child2 可以出现任意次数(0 到无界)
  • 元素以任何顺序排列
  • 元素 child3 和 child4 应该只出现一次。

For example, this xml is valid:

例如,这个 xml 是有效的:

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

but this is not (missing child3)

但这不是(失踪的孩子3)

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

采纳答案by xcut

In the schema you have in your question, child1or child2can appear in any order, any number of times. So this sounds like what you are looking for.

在您的问题中的架构中,child1或者child2可以以任意顺序出现任意次数。所以这听起来像你正在寻找的。

Edit:if you wanted only one of them to appear an unlimited number of times, the unbounded would have to go on the elements instead:

编辑:如果您只希望其中一个出现无限次,则无界将不得不继续使用元素:

Edit:Fixed type in XML.

编辑:XML 中的固定类型。

Edit:Capitalised O in maxOccurs

编辑: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>

回答by C. M. Sperberg-McQueen

The alternative formulation of the question added in a later edit seems still to be unanswered: how to specify that among the children of an element, there must be one named child3, one named child4, and any number named child1or child2, with no constraint on the order in which the children appear.

在稍后的编辑中添加的问题的替代表述似乎仍未得到解答:如何指定在元素的子元素中,必须有一个 named child3、一个 namedchild4和任何名为child1or 的数字child2,对中的顺序没有限制孩子们出现的地方。

This is a straightforwardly definable regular language, and the content model you need is isomorphic to a regular expression defining the set of strings in which the digits '3' and '4' each occur exactly once, and the digits '1' and '2' occur any number of times. If it's not obvious how to write this, it may help to think about what kind of finite state machine you would build to recognize such a language. It would have at least four distinct states:

这是一种可直接定义的正则语言,您需要的内容模型与定义字符串集的正则表达式同构,其中数字“3”和“4”各只出现一次,数字“1”和“2” ' 出现任意次数。如果不清楚如何编写它,那么考虑您将构建什么样的有限状态机来识别这种语言可能会有所帮助。它至少有四个不同的状态:

  • an initial state in which neither '3' nor '4' has been seen
  • an intermediate state in which '3' has been seen but not '4'
  • an intermediate state in which '4' has been seen but not '3'
  • a final state in which both '3' and '4' have been seen
  • 既没有看到“3”也没有看到“4”的初始状态
  • 已经看到“3”但没有看到“4”的中间状态
  • 一种中间状态,其中“4”已被看到但“3”未出现
  • '3' 和 '4' 都被看到的最终状态

No matter what state the automaton is in, '1' and '2' may be read; they do not change the machine's state. In the initial state, '3' or '4' will also be accepted; in the intermediate states, only '4' or '3' is accepted; in the final state, neither '3' nor '4' is accepted. The structure of the regular expression is easiest to understand if we first define a regex for the subset of our language in which only '3' and '4' occur:

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

(34)|(43)

To allow '1' or '2' to occur any number of times at a given location, we can insert (1|2)*(or [12]*if our regex language accepts that notation). Inserting this expression at all available locations, we get

为了允许“1”或“2”在给定位置出现任意次数,我们可以插入(1|2)*(或者[12]*如果我们的正则表达式语言接受该符号)。在所有可用的位置插入这个表达式,我们得到

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

Translating this into a content model is straightforward. The basic structure is equivalent to the regex (34)|(43):

将其转换为内容模型很简单。基本结构等价于正则表达式(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>

Inserting a zero-or-more choice of child1and child2is straightforward:

插入零个或多个child1和选择child2很简单:

<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>

If we want to minimize the bulk a bit, we can define a named group for the repeating choices of child1and child2:

如果我们希望尽量减少散装一点,我们可以定义一个名为组的重复选择child1child2

<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>

In XSD 1.1, some of the constraints on all-groups have been lifted, so it's possible to define this content model more concisely:

在 XSD 1.1 中,all取消了对-groups 的一些限制,因此可以更简洁地定义此内容模型:

<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>

But as can be seen from the examples given earlier, these changes to all-groups do not in fact change the expressive power of the language; they only make the definition of certain kinds of languages more succinct.

但是从前面给出的例子可以看出,对all-groups 的这些变化实际上并没有改变语言的表达能力;它们只会使某些语言的定义更加简洁。

回答by Alan

This is what finally worked for me:

这最终对我有用:

<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>

回答by Pavel Minaev

But from what I understand xs:choice still only allows single element selection. Hence setting the MaxOccurs to unbounded like this should only mean that "any one" of the child elements can appear multiple times. Is this accurate?

但据我了解 xs:choice 仍然只允许单元素选择。因此,像这样将 MaxOccurs 设置为 unbounded 应该只意味着“任何一个”子元素可以出现多次。这是准确的吗?

No. The choice happens individually for every "repetition" of xs:choicethat occurs due to maxOccurs="unbounded". Therefore, the code that you have posted is correct, and will actually do what you want as written.

不。对于xs:choice由于发生的每次“重复”,选择都会单独发生maxOccurs="unbounded"。因此,您发布的代码是正确的,并且实际上会按照您的意愿行事。

回答by Steven_W

You should find that the following schema allows the what you have proposed.

您应该会发现以下架构允许您提出的建议。

  <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>

This will allow you to create a file such as:

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

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

Which seems to match your question.

这似乎符合你的问题。

回答by Prabhdeep Gill

If none of the above is working, you are probably working on EDI trasaction where you need to validate your result against an HIPPA schema or any other complex xsd for that matter. The requirement is that, say there 8 REF segments and any of them have to appear in any order and also not all are required, means to say you may have them in following order 1st REF, 3rd REF , 2nd REF, 9th REF. Under default situation EDI receive will fail, beacause default complex type is

如果以上都不起作用,您可能正在处理 EDI 交易,您需要根据 HIPPA 模式或任何其他复杂的 xsd 验证结果。要求是,假设有 8 个 REF 段,并且它们中的任何一个必须以任何顺序出现,也不是全部都是必需的,这意味着您可以按以下顺序排列它们:1st REF、3rd REF、2nd REF、9th REF。默认情况下 EDI 接收会失败,因为默认复杂类型是

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

The situation is even complex when you are calling your element by refrence and then that element in its original spot is quite complex itself. for example:

当您通过引用调用元素时,情况甚至会很复杂,然后该元素在其原始位置本身就非常复杂。例如:

<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>

Solution:

解决方案:

Here simply replacing "sequence" with "all" or using "choice" with min/max combinations won't work!

在这里,简单地将“序列”替换为“全部”或将“选择”与最小/最大组合一起使用是行不通的!

First thing replace "xs:sequence" with "<xs:all>"Now,You need to make some changes where you are Referring the element from, There go to:

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

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

***Now in the above segment add trigger point in the end like this trigger_field="REF01_...complete name.." trigger_value = "38" Do the same for other REF segments where trigger value will be different like say "18", "XX" , "YY" etc..so that your record info now looks like:b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">

***现在在上面的段中在最后添加触发点,像这样 trigger_field="REF01_...完整名称.." trigger_value = "38" 对其他触发值不同的 REF 段执行相同的操作,例如“18” ", "XX" , "YY" 等等,这样你的记录信息现在看起来像:b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">



This will make each element unique, reason being All REF segements (above example) have same structure like REF01, REF02, REF03. And during validation the structure validation is ok but it doesn't let the values repeat because it tries to look for remaining values in first REF itself. Adding triggers will make them all unique and they will pass in any order and situational cases (like use 5 out 9 and not all 9/9).

这将使每个元素都是唯一的,原因是所有 REF 段(上例)都具有相同的结构,如 REF01、REF02、REF03。在验证期间,结构验证是可以的,但它不会让值重复,因为它会尝试在第一个 REF 本身中查找剩余值。添加触发器将使它们都是独一无二的,并且它们将在任何顺序和情境情况下通过(例如使用 5 出 9 而不是全部 9/9)。

Hope it helps you, for I spent almost 20 hrs on this.

希望它对你有帮助,因为我在这上面花了将近 20 个小时。

Good Luck

祝你好运