我正在尝试为书籍设计XML模式,其中需要为每个书籍条目指定唯一ID.然而它似乎没有用.以下是我正在使用的XSD,
<?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>
Run Code Online (Sandbox Code Playgroud)
我试图用这个验证的XML是,
<?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>
Run Code Online (Sandbox Code Playgroud)
即使它不应该验证罚款(我已经为2个条目使用了相同的id).我是XML的新手,如果有人能指出我在这里做错了什么,我会很感激吗?
Ian*_*rts 11
你有<xs:unique>错误的地方 - 它需要在祖先元素的定义内,Book元素应该是唯一的,而不是在Book元素定义本身.以下将强制Book ID在每个架子中是唯一的,但在不同的架子上允许相同的ID:
<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>
Run Code Online (Sandbox Code Playgroud)
如果您希望ID在所有货架上全局唯一,则将唯一约束放在该BookShelf级别并适当调整选择器:
<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>
Run Code Online (Sandbox Code Playgroud)
为了将来参考,请注意,如果您的模式有一个targetNamespace那么那些选择器将无法正常工作,因为选择器XPath中的无前缀名称始终意味着"无命名空间".您需要添加xmlns:tns="<target namespace URI>"到您的xs:schema元素,然后使用选择器tns:Shelf/tns:Book.