XML 模式仍然允许具有唯一性的重复 ID [英] XML schema still allowing duplicate id's with unique
问题描述
我正在尝试为书籍设计一个 XML 模式,其中需要为每个书籍条目指定一个唯一的 ID.但是,它似乎不起作用.下面是我正在使用的 XSD,
I am trying to design an XML schema for books where a unique ID needs to be specified for each book entry. However it just doesn't seem to work. Below is the XSD i am using,
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="BookShelf">
<xs:complexType>
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0"/>
<xs:element name="Shelf" type="ShelfType" minOccurs="1" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="ShelfType">
<xs:sequence>
<xs:element ref="Book" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Book">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:token"/>
<xs:element name="Language" type="xs:language"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
<xs:unique name="unique-bookId">
<xs:selector xpath="Book"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
</xs:schema>
我试图验证的 XML 是,
The XML I am trying to validate with this is,
<?xml version="1.0"?>
<BookShelf>
<Description>My bookshelf</Description>
<Shelf>
<Book id="1">
<Title>Seitsemän veljestä</Title>
<Language>fi</Language>
</Book>
<Book id="1">
<Title>Another title</Title>
<Language>en</Language>
</Book>
</Shelf>
</BookShelf>
即使不应该验证也很好(我对 2 个条目使用了相同的 ID).我对 XML 还很陌生,如果有人能指出我在这里做错了什么,我将不胜感激?
which is validating fine even though it should not (I've used the same id for 2 entries). I'm pretty new at XML and would appreciate if someone could please point out what I am doing wrong here?
推荐答案
放在错误的地方 - 它需要在
的定义中em>ancestor 元素,其中 Book
元素应该是唯一的,而不是在 Book
元素定义本身中.以下内容将强制每个书架内的图书 ID 是唯一的,但允许不同书架上的相同 ID:
You've got the <xs:unique>
in the wrong place - it needs to be inside the definition of the ancestor element within which the Book
elements should be unique, not in the Book
element definition itself. The following would force Book ids to be unique within each shelf, but would allow the same ID on different shelves:
<xs:element name="BookShelf">
<xs:complexType>
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0"/>
<xs:element name="Shelf" type="ShelfType" minOccurs="1" maxOccurs="10">
<xs:unique name="unique-bookId">
<xs:selector xpath="Book"/><!-- selects books on this shelf -->
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
如果您希望 ID 在所有书架中全局唯一,则将唯一约束置于 BookShelf
级别并适当调整选择器:
If instead you want the IDs to be globally unique across all shelves then put the unique constraint at the BookShelf
level and adjust the selector appropriately:
<xs:element name="BookShelf">
<xs:complexType>
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0"/>
<xs:element name="Shelf" type="ShelfType" minOccurs="1" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="unique-bookId">
<xs:selector xpath="Shelf/Book"/><!-- selects books on all shelves -->
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
为了将来参考,请注意,如果您的架构具有 targetNamespace
,那么这些选择器将无法按原样工作,因为选择器 XPath 中的无前缀名称始终意味着无命名空间".您需要将 xmlns:tns="<target namespace URI>"
添加到您的 xs:schema
元素,然后使用 tns:Shelf/的选择器tns:预订
.
For future reference, note that if your schema had a targetNamespace
then those selectors would not work as-is, because unprefixed names in selector XPaths always mean "no namespace". You would need to add xmlns:tns="<target namespace URI>"
to your xs:schema
element and then use a selector of tns:Shelf/tns:Book
.
这篇关于XML 模式仍然允许具有唯一性的重复 ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!