XML模式如何指定必须至少必须出现的选项列表?

时间:2011-07-11 19:14:24

标签: xsd

我试图指定一个选项列表(即一系列元素),其中至少必须出现一个选项。 (但不一定多于一个)。

一种有效的方法但显然是错误的方法是:

<xsd:sequence minOccurs="1" maxOccurs="unbounded">
  <xsd:choice>
    <xs:element name="apple" type="xsd:string" />
    <xs:element name="banana" type="xsd:string" />
    <xs:element name="pear" type="xsd:string" />
  </xsd:choice>
</xsd:sequence>

这种作品,但是你可以指定任何项目的多个(例如2个香蕉),并且也会丢失排序(香蕉可以在苹果之前出现)。

必须有更好的方法来做到这一点!?但是我搜索了几个小时而没找到一个。

有谁知道应该怎么做?

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

如果我理解你的问题,顺序很重要(在苹果和梨必须出现在最后之前不能出现香蕉),每种水果只允许出现一次,但必须至少有一种水果。

<xsd:choice>
    <xsd:sequence>
        <xsd:element name="apple" type="xsd:string"/>
        <xsd:element minOccurs="0" name="banana" type="xsd:string"/>
        <xsd:element minOccurs="0" name="pear" type="xsd:string"/>
    </xsd:sequence>
    <xsd:sequence>
        <xsd:element name="banana" type="xsd:string"/>
        <xsd:element minOccurs="0" name="pear" type="xsd:string"/>
    </xsd:sequence>
    <xsd:element name="pear" type="xsd:string"/>
</xsd:choice>

结果看起来有点复杂,但它不需要遍历所有组合。

答案 1 :(得分:0)

<xsd:choice minOccurs="1" maxOccurs="1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:sequence>
        <xsd:element name="apple" type="xsd:string"/>
    </xsd:sequence>
    <xsd:sequence>
        <xsd:element name="banana" type="xsd:string"/>
    </xsd:sequence>
    <xsd:sequence>
        <xsd:element name="pear" type="xsd:string"/>
    </xsd:sequence>
    <xsd:sequence>
        <xsd:element name="apple" type="xsd:string"/>
        <xsd:element name="banana" type="xsd:string"/>
    </xsd:sequence>
    <xsd:sequence>
        <xsd:element name="apple" type="xsd:string"/>
        <xsd:element name="pear" type="xsd:string"/>
    </xsd:sequence>
    <xsd:sequence>
        <xsd:element name="banana" type="xsd:string"/>
        <xsd:element name="pear" type="xsd:string"/>
    </xsd:sequence>
    <xsd:sequence>
        <xsd:element name="apple" type="xsd:string"/>
        <xsd:element name="banana" type="xsd:string"/>
        <xsd:element name="pear" type="xsd:string"/>
    </xsd:sequence>
</xsd:choice>

答案 2 :(得分:0)

您的原始问题仅涉及Schema,并未提及Java或任何其他应用程序逻辑。但是你已经说过,由于你的应用要求,@ Dan和@jasso提供的其他Schema解决方案是不够的。

由于您有一个要利用的应用程序,请在架构中记录它,然后在应用程序代码中应用您的逻辑。

架构:

<xs:annotation>
    <xs:documentation>
        At least one of apple, banana, or pear is required.
    </xs:documentation>
</xs:annotation>
<xsd:sequence>
    <xsd:element name="apple" minOccurs="0" type="xsd:string"/>
    <xsd:element name="banana" minOccurs="0" type="xsd:string"/>
    <xsd:element name="pear" minOccurs="0" type="xsd:string"/>
</xsd:sequence>

爪哇:

if (apple == null && banana == null && pear == null)
{
  throw new IllegalStateException("At least one of apple, banana or pear is required.");
}

如果您的应用程序允许您进行多阶段解析,那么您可以考虑将断言文档正式化为更正式化的内容。

Schematron非常适合此目的。

它允许您将断言规则指定为XPath表达式。然后,您可以将这些断言编译为XSLT转换,您可以在xml转换管道中应用这些转换以进行其他验证。