【问题标题】:XSD unique element XPath limitationsXSD 唯一元素 XPath 限制
【发布时间】:2015-06-10 14:31:19
【问题描述】:

为了允许一个元素出现多次但将其限制为只允许一次的元素值,我正在应用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>

这按预期工作,并给了我两次包含“DIGITALARCHIVE”的错误。 问题是这种方法迫使我在每个可能的扩展Mailpack 类型中包含unique 元素。 所以如果我例如引入Parcel 类型作为Mailpack 的扩展,然后我必须从batch/letter 元素中复制相同的unique 元素到新的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 的所有扩展都有效? (如果有的话)

【问题讨论】:

  • 我想你不能使用 XSD 1.1,是这样吗?
  • @sergioFC:恐怕 XSD 1.1 不是一个选项,不。我很想使用它,但即使在 3 年后,一个基本应用程序仍然不支持它。
  • 我能想到的唯一选择是将 列表包装在 元素中。
  • @sergioFC:这会有什么不同?之后你会将unique 元素放在哪里?
  • 在包含 列表的元素内。请注意,在我的回答中,我将其称为 而不是 .

标签: xml xpath xsd unique xsd-1.0


【解决方案1】:

通过将&lt;deliveryMethod&gt; 元素包装在(例如)&lt;deliveryMethodsList&gt; 元素中,您可以移动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>

现在您不需要 letters 列表中的 unique 元素:

<xs:element maxOccurs="unbounded" name="letter" type="Letter" />

现在以下示例无效,因为&lt;deliveryMethod&gt;DIGITALARCHIVE&lt;/deliveryMethod&gt; 出现了两次:

<?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>

【讨论】:

  • 像魅力一样工作。通过将deliveryMethod 元素包裹在一个单独的元素中而不是让它们直接“浮动”在letter 元素中,它甚至更干净。谢谢!
  • 我很高兴它成功了。我不确定这是否适合您的需求。不客气。
  • 您介意通过将DeliveryMethodsList 的大写更改为deliveryMethodsList 来更正您自己的帖子吗?审核 twats 拒绝了我的编辑,无效地声明它不会提高它的准确性。现在正在使用不一致的样式和引用。
  • 当然,而且你是对的,现在更好并更正了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多