XSD:指定一个选项必须至少有一个列表,但每个选项不超过一个

Pau*_*aul 5 xsd xml-validation

这已经让我发疯了好几个小时。我已经阅读了关于 SO 和 Internet 其余部分的所有相关 XSD 问题,但似乎仍然没有答案。

我需要一个 XML 模式,它要求至少存在一个元素列表,但每个元素可能只出现 0 或 1 次。

这类似于这个问题: XML 模式构造“任何一个或多个这些元素,但必须至少是一个”

但我无法限制上限:我显然使用maxOccurs不正确。

这是我离开我的模式的地方:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="Selects">
        <xs:sequence minOccurs="2" maxOccurs="4">
        <xs:choice>
        <xs:element name="aaa" minOccurs="1" maxOccurs="1"/>
        <xs:element name="bbb" minOccurs="1" maxOccurs="1"/>
        <xs:element name="ccc" minOccurs="1" maxOccurs="1"/>
        <xs:element name="ddd" minOccurs="1" maxOccurs="1"/>
        </xs:choice>
    </xs:sequence>
    </xs:complexType>
    <xs:element name="baseElement">
        <xs:complexType>
        <xs:sequence>
        <xs:element name="MyChoice" type="Selects"/>
            </xs:sequence>
    </xs:complexType>
    </xs:element>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

我尝试了minOccursmaxOccurs上上之选,并没有运气的元素。这是验证的 XML,但我不希望它:

<?xml version="1.0" encoding="UTF-8"?>
<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <MyChoice>
        <ddd/>
        <ddd/>
    </MyChoice>
</baseElement>
Run Code Online (Sandbox Code Playgroud)

如果可能,这是我想要的示例:

<?xml version="1.0" encoding="UTF-8"?>
<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <MyChoice>
        <ddd/>
        <aaa/>
        <ccc/>
    </MyChoice>
</baseElement>
Run Code Online (Sandbox Code Playgroud)

我希望它抱怨多个ddd元素,但允许任何或所有其他元素以任何顺序。如果我在 MyChoice 下只有一个元素,我会收到一个错误,所以至少有些东西是有效的。

我究竟做错了什么?如何防止多个相同元素验证?

更新

这是我的解决方案(来自以下答案的评论):

实际上, xs:all 做到了。我交换了所有选择,并为每个元素添加了 minOccurs="0" maxOccurs="1"。对于 xs:all,minOccurs 必须为 0 或 1,maxOccurs 必须为 1。感谢您的帮助 - 我现在可以开始了!

tom*_*ern 3

只需将选择周围的移动<xs:sequence minOccurs="2" maxOccurs="4">到您想要进一步使用它的位置即可。(您还可以删除最小/最大出现 = 1,因为这就是 xs:choice 的作用)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xs:complexType name="Selects">
    <xs:choice>
      <xs:element name="aaa" />
      <xs:element name="bbb" />
      <xs:element name="ccc" />
      <xs:element name="ddd" />
    </xs:choice>
  </xs:complexType>
  <xs:element name="baseElement">
    <xs:complexType>
      <xs:sequence minOccurs="2" maxOccurs="4">
        <xs:element name="MyChoice" type="Selects" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

这验证了以下内容:

<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <MyChoice>
    <bbb></bbb>
  </MyChoice>
  <MyChoice>
    <ccc></ccc>
  </MyChoice>
</baseElement>
Run Code Online (Sandbox Code Playgroud)

更新

我认为您已经达到了 XSD 所能实现的极限。除了为每个可能的组合定义 MyChoice 类型的“版本”(然后需要不同的名称 MyChoice1、MyChoice2 等)之外,我看不出有任何方法可以做到这一点

您还可以使用 xs:all

  <xs:complexType name="Selects">
    <xs:all minOccurs=2 maxOccurs=4>
      <xs:element name="aaa" />
      <xs:element name="bbb" />
      <xs:element name="ccc" />
      <xs:element name="ddd" />
    </xs:all>
  </xs:complexType>
Run Code Online (Sandbox Code Playgroud)

但这不会阻止你拥有<ddd/>四个