【问题标题】:How to make two different elements have unique values in the same complex type in a XSD?如何使两个不同的元素在 XSD 中的同一复杂类型中具有唯一值?
【发布时间】:2017-10-20 01:17:10
【问题描述】:

我想验证两个字段在同一个 complexType 中始终具有唯一值。我想在我的 XSD 中验证这一点,而不是直接在代码中进行。

我知道我不能在同一个 complexType 中使用类型“xs:ID”两次,不幸的是我不能使标签工作。

我已经有一个属性“bookId”,在 complexType 中使用类型“xs:ID”,所以我想使用标签来保证另一个元素“bookName”的唯一值。

我有以下结构:

<xs:complexType name="book">
    <xs:sequence>
        <xs:element name = "bookName" nillable="true" minOccurs="0">
            <xs:simpleType>
                <xs:restriction base="xs:string"
                </xs:restriction>
            </xs:simpleType>
        </xs:element>
        <xs:element name = "bookPrice" nillable="true" minOccurs="0">
            <xs:simpleType>
                <xs:restriction base="xs:decimal"
                </xs:restriction>
            </xs:simpleType>
        </xs:element>
</xs:sequence>
        <xs:attribute name="bookId" type="xs:ID" use="required"/>
</xs:complexType>

我已经尝试过执行以下操作,但没有成功:

<xs:complexType name="book">
    <xs:sequence>
        <xs:element name = "bookName" nillable="true" minOccurs="0">
            <xs:simpleType>
                <xs:restriction base="xs:string">
            </xs:simpleType>
            <xs:unique name="uniqueBookName">
                <xs:selector xpath="book"/>
                <xs:field xpath="bookName"/>
            </xs:unique>
        </xs:element>
        <xs:element name = "bookPrice" nillable="true" minOccurs="0">
            <xs:simpleType>
                <xs:restriction base="xs:decimal"
                </xs:restriction>
            </xs:simpleType>
        </xs:element>
</xs:sequence>
        <xs:attribute name="bookId" type="xs:ID" use="required"/>
</xs:complexType>

我正在使用 xml 版本 1.0。我不知道我可以从这里再尝试什么才能让它发挥作用。

有人对如何实现这一点有提示吗?非常感谢。

【问题讨论】:

    标签: xml validation jakarta-ee xsd


    【解决方案1】:

    这里需要几个答案或 cmets。

    1. 为什么您认为您不能将类型 xs:ID 分配给同一复杂类型中的两个不同元素?在 XSD 1.0 中,为了与 XML DTD 兼容,同一元素上的多个 ID 属性是被禁止的,但您使用的是元素,而不是属性。在 XSD 1.1 中,允许多个 ID 属性,就像允许多个 ID 子级一样。

      除非我遗漏了某些东西(总是可能的),否则您可能不应该相信任何信息来源告诉您 xs:ID 不能分配给同一复杂类型中的多个元素。当然,也有可能他们告诉你的内容有些微妙的不同,而你误解了一些细节。

    2. 如果您希望使用唯一性约束而不是 ID,请在其范围内 ID 必须唯一的元素上声明唯一性约束,而不是在 book 元素或 bookName 元素上。现在,您的唯一性约束指定 bookName 元素的字符串值在给定的 bookName 元素中必须是唯一的。由于 bookName 元素的字符串值永远不能超过一个,因此无论有没有 xsd:unique,都将始终满足此约束。如果您希望书名与祖先元素 bookCollection(或您所称的任何名称)是唯一的,请在此处声明唯一性约束。

      请注意,您可以要求书名是唯一的,并且单独要求书名是唯一的,或者没有两个元素的书名或书 ID 与任何其他元素的书名或书 ID 相同。在第一种情况下,书名与某个书的 ID 相同不是错误,只是与其他书的书名相同。

    3. 如果您认为在现实世界中没有两本书同名,那么您可能需要多出去走走。 ISBN 的发明正是因为不同的书有相同的标题并不少见。

      如果您认为书名可以用 xs:ID 类型合理地表示,您可能需要花一些时间查看书籍并阅读 xs:ID 类型,这要求它的值是以 a 开头的标识符字母且不包含空格。查看当前放在我桌上的书,我看不到一本标题可能是有效 xs:ID 值的书。

      价格大多以数值形式给出,因此 xsd:string 作为一种数据类型可能有点松散,对于那些关心验证的人来说。

    【讨论】:

    • 首先,感谢您的回复。 1)你是对的。我从一个值得信赖的来源看到了这一点:“一个复杂类型不能包含多个 xsd:ID 类型的属性,或者任何从 xsd:ID 派生的类型。”就我而言,我有一个属性和一个元素。所以我想在元素和属性中使用 xs:ID 不是问题。尽管如此,我还是尝试将类型 xs:ID 放在元素“bookName”中,当我测试它时,它并没有验证值的唯一性。 2)您建议我将唯一标签传递到“bookName”范围之外,但仍然在 complexType“book”之内?
    • 不,我并不是建议您在单本书的范围内应用唯一性约束(这是我试图描述的book 类型)。我建议您为在其范围内标识符必须是唯一的元素指定唯一性约束。这可能是代表书籍集合的元素,或者出现在文档根部或其他地方的元素。但是,说一本书的 ID 在该书中必须是唯一的,这完全没有意义。
    • 好吧,想象一下我确实有一个 complexType,它是 bookCollection。在那个 complexType 里面,我有一本元素书。现在想象一下,我有很多具有 type="bookCollection" 的元素。我的想法是将唯一标签直接放在 bookCollection 中,这样我就可以将约束应用于书籍,并且所有引用类型“bookCollection”的元素都将从这些约束中“受益”。问题是,我不能这样做。只有当我在父节点(具有 bookCollection 类型的元素)中声明唯一标签时它才有效,并且我最终会得到很多唯一标签。
    • XSD 唯一性和身份约束是在元素上给出的,而不是在类型上。如果您认为这种定位类似于 SQL 中的引用完整性约束,它是为列指定的,而不是列类型的一部分,那么这种定位可能更容易记住。
    猜你喜欢
    • 2021-09-22
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多