定义一个xsd:list,其中每个项目必须是唯一的?

时间:2013-01-09 06:17:52

标签: xml list xsd schema set

是否有可能在XML Schema中表达一个简单的类型,它是一个列表,它还有一个限制,即列表中的每个项目只能出现一次?换句话说,是否可以在XML Schema中定义“set”简单类型?

例如,使用以下架构:

<xs:schema version="1.1" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:simpleType name="item">
    <xs:restriction base="xs:token">
      <xs:enumeration value="A"/>
      <xs:enumeration value="B"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="itemSet">
    <xs:list itemType="item"/>
  </xs:simpleType>

  <xs:element name="root">
    <xs:complexType>
      <xs:attribute name="set" type="itemSet"/>
    </xs:complexType>
  </xs:element>

</xs:schema>

本文件验证:

<root set="A B"/>

但是,此文件也是如此,我希望验证失败,因为B会重复:

<root set="A B B"/>

我怀疑单独使用XML Schema是不可能的,但我不太了解它,所以我正在寻找确认。

2 个答案:

答案 0 :(得分:3)

在XSD 1.0中不可能,但在XSD 1.1中非常容易:

<xs:simpleType name="uniqueList">
  <xs:restriction base="xs:NMTOKENS">
    <xs:assert test="count($value) = count(distinct-values($value))"/>
  </xs:restriction>
</xs:simpleType>

答案 1 :(得分:1)

通过正则表达式可以实现。如果我们强制执行要排序的属性值,可能会容易得多。如果不是,我们可能必须使用所有组合

创建“N”模式表达式
  <xs:simpleType name="itemSet1">
<xs:restriction base="itemSet">
 <xs:pattern value="(A\s?)?(B\s?)?(C\s?)?"/>
</xs:restriction>

  <xs:element name="root">
    <xs:complexType>
      <xs:attribute name="set" type="itemSet1">
      </xs:attribute>
    </xs:complexType>
  </xs:element>

现在

<root set="A B A"/>

无效,

也是如此
<root set="B A"/>

如果您希望上述内容也有效,我们需要使用此订单为限制添加另一种模式。