1

我有一个 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 个“普通”子元素(普通 = 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>

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

4

1 回答 1

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>
于 2013-09-20T12:45:56.143 回答