XML / XSD - 如何使元素在<xs:choice>中只出现一次,可以出现多次?</xs:choice>

时间:2013-09-20 09:58:49

标签: xml xsd

我有一个XML Schema,它定义了一个complexType,如下所示:

<xs:complexType name="CompType">
    <xs:sequence>
        <xs:element name="A" type="TypeA" minOccurs="0" maxOccurs="1"/>
        <xs:choice minOccurs="1" maxOccurs="12">
            <xs:element name="B" type="TypeB"/>
            <xs:element name="C" type="TypeC"/>
            <xs:element name="D" type="TypeD"/>
        </xs:choice>
    </xs:sequence>
</xs:complexType>

我需要它来验证一个XML元素,该元素最多可以包含12个“普通”子元素(normal = TypeB,TypeC或TypeD),但可能还有一个TypeA的“特殊”子元素。

因为它有效,但我不想限制“特殊”子元素始终是第一个。换句话说,我希望能够执行类似下面的操作,并增加限制,即只能有一个TypeA子元素,并且不超过12个“普通”子元素。

<xs:complexType name="CompType">
    <xs:sequence>
        <xs:choice minOccurs="1" maxOccurs="13">
            <xs:element name="A" type="TypeA"/>
            <xs:element name="B" type="TypeB"/>
            <xs:element name="C" type="TypeC"/>
            <xs:element name="D" type="TypeD"/>
        </xs:choice>
    </xs:sequence>
</xs:complexType>

这一切都可能吗?如果是,有人可以指出如何或者至少指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

Unique Particle Attribution(UPA)限制将阻碍为 XSD 1.0 实现此目标的任何巧妙尝试。

即使你想要0或更多B,C或D并且任意顺序只有0或1 A的情况也是如此。考虑:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           version="1.0">

  <xs:element name="X" type="CompType"/>

  <xs:complexType name="CompType">
      <xs:sequence>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="B"/>
          <xs:element name="C"/>
          <xs:element name="D"/>
        </xs:choice>
        <xs:element name="A" minOccurs="0"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="B"/>
          <xs:element name="C"/>
          <xs:element name="D"/>
        </xs:choice>
      </xs:sequence>
  </xs:complexType>
</xs:schema>

验证需要预先查看多个标签,从而违反UPA。 Xerces会表达不满:

cos-nonambig: B and B (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.

问题仍然存在于maxOccurs = 12场景中,除非你想疯狂并列举所有可能性。

如果您可以使用 XSD 1.1 ,则可以使用其xs:assert设施。 (未测试:)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           version="1.1">

  <xs:element name="X" type="CompType"/>

  <xs:complexType name="CompType">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="A"/>
      <xs:element name="B"/>
      <xs:element name="C"/>
      <xs:element name="D"/>
    </xs:choice>
    <xs:assert test="(count(./A) le 1) and (count(./A) + count(./B) + count(./C) + count(./D) le 13)"/>
  </xs:complexType>
</xs:schema>