【问题标题】:<xs:all minOccurs="0" still requires the elements to exist<xs:all minOccurs="0" 仍然需要元素存在
【发布时间】:2019-09-10 23:00:28
【问题描述】:

我正在为我们的(旧)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}'.```

【问题讨论】:

    标签: xsd xsd-validation


    【解决方案1】:

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

    通过在 ProjectDefaults 和 TaskInfo 上设置 MinOccurs = 0 来解决它

    【讨论】:

    • 谢谢,出于某种原因,我认为该值会被继承。显然不是。
    【解决方案2】:

    &lt;xs:element&gt;* 上,属性minOccursmaxOccurs 的值都默认为1
    &lt;xs:all&gt;* 上,属性minOccursmaxOccurs 的值都默认为1

    * 点击链接查看规格

    这意味着以下 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>
    

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

    minOccurs="0" 表示您可以一个都不拥有,或者三个都拥有。

    也许你认为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 是必需的。这三个元素可以按任意顺序出现。

    【讨论】:

    • 那么,在 xs:all 上设置 minOccurs 和 maxOccurs 有什么意义?它们似乎对任何东西都没有任何影响。
    • @CasaDelGato 我认为在&lt;xs:all&gt; 上设置maxOccurs 没有意义,因为它默认为1,不能更高。 minOccurs 的重点是使其成为可选的能力。如果您不指定minOccurs="0",则它是必需的,这将使ProductPool 成为必需。
    • 好吧,我(再次)对一些我读到的关于 xsd 1.1 for xs:all 更改的 cmets 感到困惑。
    猜你喜欢
    • 2014-12-22
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2022-01-09
    • 2013-06-02
    • 2012-11-05
    相关资源
    最近更新 更多