使用XSD进行XML验证:如何避免关注元素的顺序?

45

我有以下的XSD代码:

<xsd:complexType name="questions">
    <xsd:sequence>
        <xsd:element name="location" type="location"/>
        <xsd:element name="multipleChoiceInput" type="multipleChoiceInput" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element name="textInput" type="textInput" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element name="pictureInput" type="pictureInput" minOccurs="0"/>
    </xsd:sequence>
</xsd:complexType>

这里的问题是:元素位置、multipleChoiceInput等必须按照它们被声明的顺序出现。我不想让这种情况发生,在验证过程中,序列应该不相关。我该如何实现这一点?

我尝试过的另一个可能性是:

<xsd:complexType name="questions">

        <xsd:choice maxOccurs="unbounded">   
            <xsd:element name="location" type="location"/>  
            <xsd:element name="multipleChoiceInput" type="multipleChoiceInput" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="textInput" type="textInput" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="pictureInput" type="pictureInput" minOccurs="0" maxOccurs="1"/>
        </xsd:choice>            

</xsd:complexType>
在这个例子中,序列的顺序不再重要,我可以拥有任意数量的元素("all"不能让我这样做)。但是,我仍然面临min-和maxOccurs的问题。在此示例中,我可以拥有尽可能多的"pictureInput",这违反了我想要只有0个或1个的约束条件。
非常感谢你的帮助!
3个回答

56
<xsd:complexType name="questions">
    <xsd:all>
        <xsd:element name="location" type="location"/>
        <xsd:element name="multipleChoiceInput" type="multipleChoiceInput"/>
        <xsd:element name="textInput" type="textInput"/>
        <xsd:element name="pictureInput" type="pictureInput"/>
    </xsd:all>
</xsd:complexType>

注意:我已将“sequence”更改为“all”

“Sequence”强制按照定义的顺序进行排序。如果顺序无关紧要,则使用“all”。

如果有元素可能会出现多次,则可以使用xsd:any。

<xsd:complexType name="questions">
    <xsd:sequence>
        <xsd:any minOccurs="0"/>
    </xsd:sequence>
</xsd:complexType>

您可以在以下链接中找到xsd:any的详细信息:

https://www.w3schools.com/xml/schema_complex_any.asp


3
感谢您回答YoK,但在我的情况下不能使用“all”,因为“all”要求元素仅出现一次(min-和maxOccurs只能接受值0和1)。 - jcborges
1
那么,也许 <xs:any> 就是你的好朋友。 - Tomalak
1
在这种情况下需要使用“Ya”。答案也将会更新。 - YoK
再次感谢大家,但是"ANY"和"ALL"都没有考虑以下两点: 1)我想要一个且仅一个元素"location" 2)我想要0或1个元素"pictureInput"... 期待其他建议。 - jcborges
你验证过 "ALL" 不起作用吗? 因为在以下链接中说:all 元素提供了一个 XML 表示,描述了一组无序的元素类型。对于与 XML Schema 文档中 all 元素相关联的每个元素类型,在相应的 XML 实例中必须有一个相应的元素。但是,它们可以以任意顺序出现。实际上,根据与相应元素类型相关联的 minOccurs 和 maxOccurs 属性的值,每种类型可能有零个或多个元素。 http://www.xmlschemareference.com/allElement.html - YoK
显示剩余2条评论

23

我来晚了,但是我遇到了同样的问题并找到了解决方案:

<xsd:complexType name="questions">
    <xsd:choice maxOccurs="unbounded">
        <xsd:element name="location" type="location"/>
        <xsd:element name="multipleChoiceInput" type="multipleChoiceInput"/>
        <xsd:element name="textInput" type="textInput"/>
        <xsd:element name="pictureInput" type="pictureInput"/>
    </xsd:choice>
</xsd:complexType>

关键是将xs:choice与maxOccurs="unbounded"结合使用。 如果只使用xs:all,则只允许一个。

添加的内容: 虽然xs:any可以工作,但它不会限制您的选择为列出的四个元素。 它将允许任何东西,这基本上违背了架构的目的。


1
对我来说,这是解决这个问题的最佳方法,尽管它并不完美。在这种情况下,它没有遵守必须有0或1个“pictureInput”的要求。您可以添加多个,并且设置maxOccurs无法防止这种情况(因为选择本身是无限制的)。 - Ron Deijkers

1
在此晚参与,但是是否结合使用 minOccursmaxOccurs<xsd:all> 不可行呢?
<xsd:complexType name="questions">
    <xsd:all>
        <xsd:element name="location" type="location" minOccurs="0" maxOccurs="1"/>
        <xsd:element name="multipleChoiceInput" type="multipleChoiceInput" minOccurs="0" maxOccurs="1"/>
        <xsd:element name="textInput" type="textInput" minOccurs="0" maxOccurs="1"/>
        <xsd:element name="pictureInput" type="pictureInput" minOccurs="0" maxOccurs="1"/>
    </xsd:all>
</xsd:complexType>

1
不行,因为在任何一个中,你不能定义maxOccurs大于1。 - sotix
@sotix:我不理解你的评论:答案使用了 all 而不是 any,并且也没有 maxOccurs > 1。所以使用 all 实际上不会起作用吗? - Marcus Mangelsdorf
@MarcusMangelsdorf 好久不见了,所以我只能重新阅读。根据被接受的答案,all 不能包含 maxOccurs > 1,这是原问题的一部分。所以我猜我在之前的评论中混淆了 allany - sotix
1
你说得完全正确,它对于原始问题不起作用,肯定是一个打字错误。但是@gaelicyoda的代码示例仍然是正确的并且有效(这正是我所需要的),尽管maxOccurs="1"是多余的,因为<all>元素默认为minOccurs="1"maxOccurs="1" - Marcus Mangelsdorf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接