[请注意,如果您实际展示了一些 XML,那么理解您的问题会更容易一些。事实上,任何答案都必须部分基于对您的散文描述旨在描述的 XML 构造的猜测;那么,带着一粒盐把它们拿走。]
如果我理解您,您希望施加几个限制(此处编号以供参考):
每个<element>
元素都显示为元素的子<item>
元素。
每个<element>
and<item>
元素都有一个number
属性,其值为一个标识号;每个number
属性的值是一个有限的十进制数字序列。
每个元素的标识号在某个标识的容器元素(例如文档元素)中的<item>
所有元素中都是唯一的。<item>
每个元素的标识号在同一容器元素中的<element>
所有元素中都是唯一的。<element>
(或者你的意思是它<element>
在包含项目中的所有元素中都是唯一的?我无法从你的描述中看出。)
每个<element>
元素的标识号将以父<item>
元素的标识号作为前缀。
每个<element>
元素的标识号将比父<item>
元素的标识号长两位数。
以下模式强加了这些约束。由于您提到断言,我假设您能够使用 XSD 1.1。(如果你没有 1.1,你就没有断言。)
<xs:schema
targetNamespace="http://example.com/elements-and-items"
xmlns:tns="http://example.com/elements-and-items"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="test" type="tns:test">
<xs:unique name="item-unique">
<xs:annotation>
<xs:documentation>
Ensure that the number attribute on each
item is unique within the 'test' element.
(Enforces constraint 3.)
</xs:documentation>
</xs:annotation>
<xs:selector xpath=".//tns:item"/>
<xs:field xpath="@number"/>
</xs:unique>
<xs:unique name="element-unique">
<xs:annotation>
<xs:documentation>
Ensure that the number attribute on each
item is unique within the 'test' element.
(Enforces constraint 4. If 'element' elements
are only supposed to be unique within 'item'
elements, then move this to the declaration of
the 'item' element, and forget constraint
5.)
</xs:documentation>
</xs:annotation>
<xs:selector xpath=".//tns:item/tns:element"/>
<xs:field xpath="@number"/>
</xs:unique>
</xs:element>
<xs:element name="item" type="tns:item"/>
<xs:element name="element" type="tns:element"/>
<xs:complexType name="test">
<xs:annotation>
<xs:documentation>
Each 'test' element contains a sequence of
'item' elements.
(Helps enforce constraint 1.)
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="tns:item" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="item">
<xs:annotation>
<xs:documentation>
Each 'item' element contains a sequence of
'element' elements.
(Helps enforce constraint 1.)
Each 'item' element has a 'number' attribute,
of type 'tns:number'.
(Enforces constraint 2 for 'item' elements.)
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="tns:element" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="number" type="tns:number"/>
<xs:assert test="
every $id in ./@number satisfies
every $e in .//tns:element/@number satisfies
starts-with($e,$id)">
<xs:annotation>
<xs:documentation>
Each element-identifying number has the
item-identifying number of the containing item
as a prefix.
Enforces constraint 5.
</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="
every $id in ./@number satisfies
every $e in .//tns:element/@number satisfies
string-length($e) = string-length($id) + 2">
<xs:annotation>
<xs:documentation>
Each element-identifying number is two
digits longer than the item-identifying
number of the containing item.
Enforces constraint 6.
</xs:documentation>
</xs:annotation>
</xs:assert>
</xs:complexType>
<xs:complexType name="element" mixed="true">
<xs:annotation>
<xs:documentation>
Each 'element' element has a 'number' attribute,
of type 'tns:number'.
(Enforces constraint 2 for 'element' elements.)
</xs:documentation>
</xs:annotation>
<xs:sequence/>
<xs:attribute name="number" type="tns:number"/>
</xs:complexType>
<xs:simpleType name="number">
<xs:restriction base="xs:string">
<xs:pattern value="\d+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
请注意,每个 XSD 1.1 处理器都需要在断言中支持相当少的 XPath 2.0 子集;我没有努力尝试在该子集中编写断言(但我也没有努力决定它们是否可以写入该子集中)。
一个有效的实例,在结构上与您的非 XML 示例相同(据我所知):
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://example.com/elements-and-items
uniqueness.xsd"
xmlns="http://example.com/elements-and-items">
<item number="1">
<element number="101"/>
<element number="102"/>
<element number="103"/>
</item>
<item number="2">
<element number="201"/>
<element number="205"/>
<element number="206"/>
</item>
<item number="3">
<element number="303"/>
<element number="301"/>
<element number="302"/>
</item>
</test>
通过违反每个约束来说明每个约束的无效实例;如果架构正在完成其工作,则应检测到每个违规行为,并应使相应的元素或项目无效:
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://example.com/elements-and-items
uniqueness.xsd"
xmlns="http://example.com/elements-and-items">
<item number="1">
<element number="101"/>
<element number="102"/>
<element number="103"/>
</item>
<item number="1">
<!--* duplicate item number, invalid
* (violates constraint 3)
*-->
<element number="104"/>
<element number="105"/>
<element number="106"/>
</item>
<item number="2">
<element number="107">
element number unique but doesn't match item number
(violates constraint 5)
</element>
<element number="202"/>
<element number="202">
item number not unique
(violates constraint 4)
</element>
</item>
<item number="3">
<element number="303"/>
<element number="301"/>
<element number="3141592">
item number unique and matches item number
but more than two digits longer
(violates constraint 6)</element>
</item>
</test>