对 complexType 而不是元素的唯一约束
Unique constraint on a complexType instead of an element
我有以下 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
。
有没有一种方法可以简单地告诉我我想要一个特定的结构并且它包含独特的元素,而不必在任何地方重复独特的约束?
简答,这是不可能的。 XSD 1.0 和 1.1 都将身份约束置于元素下;约束不能全局定义,因此除了封闭元素之外,本身没有 "reuse" 。给定你的场景(不同的元素名称满足不同的需求)是不可能重用的。
作为Petru Gardea said in
Both XSD 1.0 and 1.1 place the identity constraints under an element
所以你必须给每个元素添加xs:unique,但是如果你使用XSD 1.1你只能定义一次完整的xs:unique 然后在其余元素中使用 xs:unique ref="name"。这对您无效,因为您使用的是 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>
我有以下 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
。
- 这行得通,但导致 XSD 文档中出现大量
有没有一种方法可以简单地告诉我我想要一个特定的结构并且它包含独特的元素,而不必在任何地方重复独特的约束?
简答,这是不可能的。 XSD 1.0 和 1.1 都将身份约束置于元素下;约束不能全局定义,因此除了封闭元素之外,本身没有 "reuse" 。给定你的场景(不同的元素名称满足不同的需求)是不可能重用的。
作为Petru Gardea said in
Both XSD 1.0 and 1.1 place the identity constraints under an element
所以你必须给每个元素添加xs:unique,但是如果你使用XSD 1.1你只能定义一次完整的xs:unique 然后在其余元素中使用 xs:unique ref="name"。这对您无效,因为您使用的是 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>