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

发布于 2024-12-17 07:23:24 字数 2502 浏览 4 评论 0原文

这已经让我发疯了好几个小时了。我已经阅读了 SO 上的所有相关 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>

我已经在选择和元素上尝试了 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>

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

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

我希望它抱怨多个 ddd 元素,但允许任何或全部其他人以任何顺序。如果 MyChoice 下只有一个元素,我会收到错误消息,所以至少有些东西可以工作。

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

更新

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

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

This has been driving me mad for hours. I've read every relevant XSD question on SO and the rest of the Internet it seems and still the answer eludes me.

I need an XML schema that requires at least one of list of elements be present, but each element may appear only 0 or 1 times.

This is similar to this question:
XML schema construct for "any one or more of these elements but must be at least one"

but I was unable to constrain the upper limit: I am apparently using maxOccursincorrectly.

Here's where I left off with my schema:

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

I've tried the minOccurs and maxOccurs on the choice and the element with no luck. Here is XML that validates, though I don't want it to:

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

Here's an example of what I would like, if possible:

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

I would like it to complain about the multiple ddd elements but allow any or all of the others in any order. I get an error if I only have one element under MyChoice so at least something works.

What am I doing wrong? How do I prevent multiple of the same element from validating?

UPDATE

This was my solution (from comments on answer below):

Actually, xs:all did the trick. I swapped the choice for all and added minOccurs="0" maxOccurs="1" to each element. With xs:all, minOccurs must be either 0 or 1 and maxOccurs must be 1. Thanks for your help - I'm good to go now!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

娇柔作态 2024-12-24 07:23:24

只需将 从选项周围移动到您想要进一步使用它的位置即可。 (您还可以删除最小/最大出现 = 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>

这验证了以下内容:

<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <MyChoice>
    <bbb></bbb>
  </MyChoice>
  <MyChoice>
    <ccc></ccc>
  </MyChoice>
</baseElement>

更新

我认为您已经达到了使用 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>

但这会不会阻止您拥有四个

Just move the <xs:sequence minOccurs="2" maxOccurs="4"> from around the choice to the point where you want to use it further down. (you can also remove the min/max occurs = 1 as this is what xs:choice does)

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

This validates the following:

<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <MyChoice>
    <bbb></bbb>
  </MyChoice>
  <MyChoice>
    <ccc></ccc>
  </MyChoice>
</baseElement>

UPDATE

I think you are reaching the limit of what you can achieve with XSD. I can't see any way you can do this other than by defining a "version" of the MyChoice type for every single combination possible (which will then need different names MyChoice1, MyChoice2 etc)

You can also use 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>

but this will not prevent you from having four <ddd/>'s

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文