<xs:all minOccurs="0" 仍然要求元素存在

<xs:all minOccurs="0" still requires the elements to exist

我正在为我们的(旧)XML 输出编写架构,运行 遇到元素可能包含一些子元素的问题。我在架构中使用 "xs:all minOccurs="0",但是当我根据 XML 进行验证时,它需要每个子元素至少有一个实例。

    <xs:element name="Project">
        <xs:complexType>
            <xs:all minOccurs="0" maxOccurs="1">
                <xs:element ref="lit:ProductPool" minOccurs="1"/>
                <xs:element ref="lit:ProjectDefaults"/>
                <xs:element ref="lit:TaskInfo"/>
            </xs:all>
            <xs:attribute name="Name" type="lit:TextType_2010"/>
... a bunch more

然后当我用它来验证一些只有 "ProductPool" 子元素的 XML 时,验证器抱怨其他 2 个丢失并且是必需的。

    Reason: The following elements are expected after this location (see below)
        'lit:TaskInfo'
        'lit:ProjectDefaults'
    Error location: MetrixXML / Project
    Details
        cvc-complex-type.1.4: The content for element <Project> is incomplete.
        cvc-type.3.2: Element <Project> is not valid with respect to type definition '{anonymous}'.
        cvc-elt.5.2.1: The element <Project> is not valid with respect to the actual type definition '{anonymous}'.```

那是因为你的MinOccurs在All节点上,而不是在ProjectDefaults或TaskInfo上,默认情况下它们将是minOccurs一次。所以如果 ProductPool 不存在,它不会抱怨,但是一旦你有 ProductPool,它就会期待其他两个。

通过在 ProjectDefaults 和 TaskInfo

上设置 MinOccurs = 0 来解决它

<xs:element>*上,属性minOccursmaxOccurs的值都默认为1
<xs:all>* 上,属性 minOccursmaxOccurs 的值都默认为 1.

* 点击link查看规格

这意味着以下 3 个构造是相同的:

<!-- As defined in question -->
<xs:all minOccurs="0" maxOccurs="1">
    <xs:element ref="lit:ProductPool" minOccurs="1"/>
    <xs:element ref="lit:ProjectDefaults"/>
    <xs:element ref="lit:TaskInfo"/>
</xs:all>
<!-- Without specifying values that are same as defaults -->
<xs:all minOccurs="0">
    <xs:element ref="lit:ProductPool"/>
    <xs:element ref="lit:ProjectDefaults"/>
    <xs:element ref="lit:TaskInfo"/>
</xs:all>
<!-- Specifying values, even if same as defaults -->
<xs:all minOccurs="0" maxOccurs="1">
    <xs:element ref="lit:ProductPool" minOccurs="1" maxOccurs="1"/>
    <xs:element ref="lit:ProjectDefaults" minOccurs="1" maxOccurs="1"/>
    <xs:element ref="lit:TaskInfo" minOccurs="1" maxOccurs="1"/>
</xs:all>

这意味着如果 all 在实际 XML 中使用,通过存在 ProductPoolProjectDefaultsTaskInfo 中的任何一个,那么 3 个都必须存在

minOccurs="0" 表示您可以拥有 none 个,或全部三个。

也许你认为minOccurs默认为0,在这种情况下你应该这样写:

<xs:all minOccurs="0">
    <xs:element ref="lit:ProductPool"/>
    <xs:element ref="lit:ProjectDefaults" minOccurs="0"/>
    <xs:element ref="lit:TaskInfo" minOccurs="0"/>
</xs:all>

这样的定义,ProductPool是可选的,可以单独出现。 ProjectDefaultsTaskInfo 也是可选的,但如果其中一个存在,则 ProductPool 是必需的。这三个元素可以以任意顺序出现。