首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >XSD -如何允许元素在任意顺序中任意次数?

XSD -如何允许元素在任意顺序中任意次数?
EN

Stack Overflow用户
提问于 2010-02-18 16:44:50
回答 7查看 121.6K关注 0票数 119

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

  • 允许指定的子元素出现任意次数(0到无界)
  • 允许子元素按任何顺序排列

我环顾四周,发现了各种各样的解决方案,比如

代码语言:javascript
运行
复制
<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: selection仍然只允许单个元素的选择。因此,将MaxOccurs设置为这样的无界只能意味着子元素的“任何一个”可以多次出现。这个准确吗?

如果上面的解决方案是不正确的,我如何才能实现上述我在我的要求?

编辑:如果需求如下所示呢?

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

例如,这个xml是有效的:

代码语言:javascript
运行
复制
<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>

但这不是(缺少child3)

代码语言:javascript
运行
复制
<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-02-18 17:14:59

在您的问题中的架构中,child1child2可以以任意顺序、任意次数出现。这听起来像是你要找的东西。

如果您只想让它们中的一个出现无限次,那么无限的元素就必须放在元素上:

代码语言:javascript
运行
复制
<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>
票数 69
EN

Stack Overflow用户

发布于 2012-08-17 20:13:47

在后面的编辑中添加的问题的替代形式似乎仍有待回答:如何指定元素的子元素中必须有一个名为child3、一个名为child4、以及任何名为child1child2的数字,而不限制子元素的出现顺序。

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

  • 一种没有“3”或“4”的初始状态
  • 一种中间状态,在这种状态中,“3”已经出现,而不是“4”
  • 一种中间状态,在这种状态中,“4”已经出现,而不是“3”
  • “3”和“4”都被看到的最后一种状态

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

代码语言:javascript
运行
复制
(34)|(43)

为了允许'1‘或'2’在给定的位置发生任意次数,我们可以插入(1|2)* (如果正则表达式接受这个表示法,也可以插入[12]* )。将该表达式插入所有可用位置,我们将得到

代码语言:javascript
运行
复制
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*

将其转换为内容模型很简单。基本结构等价于regex (34)|(43)

代码语言:javascript
运行
复制
<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的零或多个选项很简单:

代码语言:javascript
运行
复制
<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>

如果我们想要将体积最小化一点,我们可以为child1child2的重复选择定义一个命名组

代码语言:javascript
运行
复制
<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>

在XSD1.1中,all-groups上的一些约束已经解除,因此可以更简洁地定义这个内容模型:

代码语言:javascript
运行
复制
<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-groups的这些更改实际上并没有改变语言的表达能力;它们只会使某些语言的定义更加简洁。

票数 117
EN

Stack Overflow用户

发布于 2011-04-20 20:12:59

这就是我终于成功的原因:

代码语言:javascript
运行
复制
<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>
票数 53
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2290360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档