对complexType而不是元素的唯一约束

时间:2015-09-28 15:39:53

标签: xsd

我有以下XSD结构:

<xs:schema xmlns:ns="http://abc/">
  ...
  <xs:element name="abc">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="map"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  ...
  <xs:element name="map">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="entry" type="ns:MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
    <xs:unique name="entry">
      <xs:selector xpath="entry"/>
      <xs:field xpath="key"/>
    </xs:unique>
  </xs:element>
  <xs:complexType name="MapEntryType">
    <xs:sequence>
      <xs:element name="key" type="xs:string"/>
      <xs:element name="value" type="xs:anyType"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

这正在发挥作用。

map元素现在必须根据包装器的不同而被称为不同的元素,因此名称有时为map,有时为properties,有时为options

因此,我想对map元素进行泛化。

我尝试了以下操作:

  • 使map成为xs:complexType并将ref更改为type
    • 导致xs:unique未被接受且失败
  • map改为xs:complexType,将ref更改为type并将xs:unique约束移至元素定义。
    • 这有效但导致XSD在文档中出现了很多xs:unique

有没有办法简单地告诉我想要一个特定的结构,它包含独特的元素,而不必在任何地方重复唯一约束?

2 个答案:

答案 0 :(得分:4)

Petru Gardeahis answer中说{/ 3}}

  

XSD 1.0和1.1都将身份约束置于元素

所以你必须为每个元素添加xs:unique,但如果使用XSD 1.1,则只能定义一次完整的 xs:unique ,然后在其余元素中定义使用 xs:unique ref =&#34; name&#34; 。这对你来说无效,因为你正在使用XSD 1.0,但我在这里为未来的XSD 1.1用户提供了这个好问题。

示例(为清晰起见,删除了名称空间):

<xs:element name="map">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="entry" type="MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <!-- Only completely defined once -->
    <xs:unique name="uniqueEntry">
        <xs:selector xpath="entry"/>
        <xs:field xpath="key"/>
    </xs:unique>
</xs:element>

<xs:element name="hashMap">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="entry" type="MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <!-- Referenced here and every other time -->
    <xs:unique ref="uniqueEntry"/>
</xs:element>

答案 1 :(得分:3)

简短回答,这是不可能的。 XSD 1.0和1.1都将身份约束置于元素下;约束不能全局定义,因此除了封闭元素之外,本身没有“重用”。鉴于您的场景(针对不同需求的不同元素名称),无法重用。