为了允许元素多次出现但将其限制为仅允许一次的元素值,我应用了unique
元素。由于XSD 1.0中的XPath限制,我只是以低效的方式工作。遗憾的是,XSD 1.1不适合我。
以下是XSD的简化版本:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="DeliveryMethod">
<xs:restriction base="xs:string">
<xs:enumeration value="POST"/>
<xs:enumeration value="DIGITALARCHIVE"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="Mailpack">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="deliveryMethod" type="DeliveryMethod"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Letter">
<xs:complexContent>
<xs:extension base="Mailpack">
<xs:sequence>
<xs:element name="content" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="batch">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="id" type="xs:string"/>
<xs:choice>
<xs:element maxOccurs="unbounded" name="letter" type="Letter">
<xs:unique name="oneOfEachDeliveryMethodType">
<xs:selector xpath="deliveryMethod"/>
<xs:field xpath="." />
</xs:unique>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
使用以下XML:
<?xml version="1.0" encoding="utf-8"?>
<batch>
<id>123</id>
<letter>
<deliveryMethod>POST</deliveryMethod>
<deliveryMethod>DIGITALARCHIVE</deliveryMethod>
<deliveryMethod>DIGITALARCHIVE</deliveryMethod>
<content>Narf!</content>
</letter>
</batch>
这可以按预期工作,并给我一个错误,&#34; DIGITALARCHIVE&#34;包含两次。
问题是这种方法迫使我在每种可能的扩展unique
类型中包含Mailpack
元素。
所以如果我,例如引入Parcel
类型作为Mailpack
的扩展名,然后我必须从新unique
元素中的batch/letter
元素复制相同的batch/parcel
元素。
如下所示,unique
元素的deliveryMethod
元素不是一个选项,因为XSD XPath中不允许使用..
父选择器。
<xs:complexType name="Mailpack">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="deliveryMethod" type="DeliveryMethod">
<xs:unique name="oneOfEachDeliveryMethodType">
<xs:selector xpath="deliveryMethod"/>
<xs:field xpath=".." />
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
将其作为batch
元素的一部分直接导致同样的问题。
如何只包含unique
元素一次,但是要计算Mailpack
的所有扩展名? (如果有的话)
答案 0 :(得分:2)
通过将<deliveryMethod>
元素包装在(例如)<deliveryMethodsList>
元素中,您可以移动unique
元素,这样您只需编写一次。
例如,您只需将Mailpack
complexType 替换为以下内容:
<xs:complexType name="Mailpack">
<xs:sequence>
<xs:element name="deliveryMethodsList">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="deliveryMethod" type="DeliveryMethod"/>
</xs:sequence>
</xs:complexType>
<!-- Unique is only placed here -->
<xs:unique name="oneOfEachDeliveryMethodType">
<xs:selector xpath="deliveryMethod"/>
<xs:field xpath="." />
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
现在您不需要字母列表中的unique
元素:
<xs:element maxOccurs="unbounded" name="letter" type="Letter" />
现在,以下示例无效,因为<deliveryMethod>DIGITALARCHIVE</deliveryMethod>
出现两次:
<?xml version="1.0" encoding="utf-8"?>
<batch>
<id>123</id>
<letter>
<deliveryMethodsList>
<deliveryMethod>POST</deliveryMethod>
<deliveryMethod>DIGITALARCHIVE</deliveryMethod>
<deliveryMethod>DIGITALARCHIVE</deliveryMethod>
</deliveryMethodsList>
<content>Narf!</content>
</letter>
</batch>