25

我正在尝试设置类似于“序列”的模式的一部分,其中所有子元素都是可选的,但至少有一个元素必须存在,并且可能不止一个。

我尝试执行以下操作,但 XMLSpy 抱怨“内容模型包含无法唯一确定的元素 <element name="DateConstant"> 和 <element name="DateConstant">。”:

    <xs:choice>
        <xs:sequence>
            <xs:element name="DateConstant"/>
            <xs:element name="TimeConstant"/>
        </xs:sequence>
        <xs:element name="DateConstant"/>
        <xs:element name="TimeConstant"/>
    </xs:choice>

可以做到这一点(如果可以,如何做到)?

一些澄清:我只想允许同名的每个元素之一。可以有一个“DateConstant”和/或一个“TimeConstant”,但不能有两个。Gizmo 的答案符合我的要求,但对于大量元素来说是不切实际的。赫斯特的回答允许两个或多个同名元素,这是我不想要的。

4

3 回答 3

26

试试这个:

<xs:choice>
  <xs:sequence>
    <xs:element name="Elem1" />
    <xs:element name="Elem2" minOccurs="0" />
    <xs:element name="Elem3" minOccurs="0" />
  </xs:sequence>
  <xs:sequence>
    <xs:element name="Elem2" />
    <xs:element name="Elem3" minOccurs="0" />
  </xs:sequence>
  <xs:element name="Elem3" />
</xs:choice>

这样做,你强制要么选择第一个元素,然后其余的是可选的,要么是第二个元素,其余的是可选的,要么是第三个元素。

我希望这应该做你想做的事。

当然,您可以将子序列分组,以避免在您意识到错过一个元素时在每个序列中重复一个元素。

于 2008-09-19T07:45:28.410 回答
19

根据http://msdn.microsoft.com/en-us/library/aa468557.aspx#understandxsd_topic5上的 MSDN 上标题为“理解 XML 架构”的技术文章 , 您可以利用诸如minOccurs之类的选项定义(合成器)本身的约束:

“在合成器上使用出现约束适用于整个组”

(请参阅使用嵌套复杂类型的更复杂的示例和 AuthorType 示例)

您将您的要求声明为“必须存在至少一个元素,并且可能有多个元素”。因此,我建议您尝试以下方法:

<xs:choice minOccurs="1" maxOccurs="unbounded">
    <xs:element name="DateConstant" type="..."/>
    <xs:element name="TimeConstant" type="..."/>
</xs:choice>
于 2008-09-19T08:56:33.840 回答
2

@赫斯特,

不幸的是,您未能理解最初的问题。当所有具有 minOccurs="0" 的元素作为选项包含时,将自动满足将 minOccurs="1" 放置在选项上。

因此,您未能考虑原始海报要求的“至少一个”,因为没有元素正确满足两个完全可选元素的 1 次出现。

到目前为止,我无法找到解决方案,因为 minOccur/maxOccur 都与定义它们的组有关,并且与节点的总数无关。您也不能多次使用选择元素来定义相同的命名元素,否则它会变得“模棱两可”。我已经看到一些示例使用引用而不是特定类型的元素,但我相信这会使 microsoft XSD 解析器失败。

<xs:choice minOccurs="1" maxOccurs="1">
  <xs:sequence minOccurs="1" maxOccurs="1">
    <xs:element name="Elem1" minOccurs="1" maxOccurs="1" />
    <xs:element name="Elem2" minOccurs="0" maxOccurs="1" />
  </xs:sequence>
  <xs:sequence >
    <xs:element name="Elem2" minOccurs="1" maxOccurs="1" />
  </xs:sequence>
</xs:choice>

在这里你可以看到要么你有第一个序列(它必须有 Elem1,但可能有 Elem2 可选),或者你有第二个序列(它必须有 Elem2)。

因此,您现在拥有这两个元素中的“任何一个或多个”。当然,随着您需要为所有可能的组合提供额外的选择,您拥有的选项越多,这就会变得越复杂。

于 2013-01-14T03:47:39.517 回答