XSD独特元素XPath限制

时间:2015-06-10 14:31:19

标签: xml xpath xsd unique xsd-1.0

为了允许元素多次出现但将其限制为仅允许一次的元素值,我应用了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的所有扩展名? (如果有的话)

1 个答案:

答案 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>