有没有办法使用XSD强制XML列表中的项目之间的唯一性?

时间:2011-05-04 18:06:16

标签: xml validation list xsd

我有一个XML文件和一个相应的XSD文件 在XSD文件中,我定义了一个列表属性,其中列表中的项是枚举的一部分。

这是我正在做的一个例子。

<xs:simpleType name="Colors">
    <xs:list itemType="ColorEnum"/>
</xs:simpleType>

<xs:simpleType name="ColorEnum">
    <xs:restriction base="xs:token">
        <xs:enumeration value="Red"/>
        <xs:enumeration value="Blue"/>
        <xs:enumeration value="Green"/>
    </xs:restriction>
</xs:simpleType>

<xs:element name="Color">
    <xs:complexType>
        <xs:attribute name="ColorList" type="Colors" />
    </xs:complexType>
</xs:element>

XML看起来像这样:

<Color ColorList="Red Blue Green"></Color>

有没有办法确保列表中的元素是唯一的?例如,有没有办法阻止Red两次进入此列表?

3 个答案:

答案 0 :(得分:4)

我认为唯一的方法是使用xsd:pattern。你想要:

<xs:simpleType name="ColorEnum">
 <xs:restriction base="xs:string">
   <xs:pattern value="(Red){0,1}\s(Blue){0,1}\s(Green){0,1}"/>
 </xs:restriction>
</xs:simpleType>

这也应该强制执行订单。我的意思是你不能提供序列“蓝绿红”。无论如何,它应该是一个起点。


编辑非常讨厌:

<xs:simpleType name="ColorEnum">
 <xs:restriction base="xs:string">
   <xs:pattern value="((Red)?\s(Blue)?\s(Green)?)|((Red)?\s(Green)?\s(Blue)?)|((Green)?\s(Blue)?\s(Red)?)|((Green)?\s(Red)?\s(Blue)?)|((Blue)?\s(Green)?\s(Red)?)|((Blue)?\s(Red)?\s(Green)?)"/>
 </xs:restriction>
</xs:simpleType>

修改

组合数由序列中使用的元素总数的阶乘数给出。我希望你不会超过三个元素:)

答案 1 :(得分:1)

在XSD 1.1(现在可在Xerces和Saxon中使用)中,你可以做到

<xs:assertion test="count(tokenize($value, '\s+')) = 
                    count(distinct-values(tokenize($value, '\s+')))"/>

答案 2 :(得分:0)

我担心xs:enumeration这是不可能的,你可以使用一些讨厌的正则表达式:

  <xs:simpleType name="ColorEnum">
    <xs:restriction base="xs:string">
      <xs:pattern value="(Red)?( Blue)?( Green)?"/>
    </xs:restriction>
  </xs:simpleType>

在这种情况下,元素的顺序是固定的。