2013-02-15 9 views
5

各ブックエントリに一意のIDを指定する必要がある書籍のXMLスキーマを設計しようとしています。しかし、それは動作していないようです。以下は、私が使用していXSDは、私がこれを検証しようとしていますXMLは、XMLスキーマでユニークな重複IDが許可されています

それは(私は同じIDを使用していたべきではないにもかかわらず、細かい検証している
<?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> 

で、

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

です2エントリー)。私はXMLでかなり新しく、誰かが私がここで間違っていることを指摘してくれるか気になるでしょうか?

答えて

10

あなたは間違った場所に<xs:unique>を持っている - それは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> 

代わりにあなたは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> 

は、あなたのスキーマがtargetNamespaceがあった場合は、そのままセレクタのXPathでプレフィックスのない名前は常に「名前空間」を意味していないので、それらのセレクタは、動作しないことに注意してください。 xs:schema要素にxmlns:tns="<target namespace URI>"を追加し、tns:Shelf/tns:Bookのセレクタを使用する必要があります。

3

具体的には数字をID値として使用する必要がありますか?そうでない場合、一つの可能​​性がid属性としてxs:IDを使用していることxs:stringの代わりに入力します。

<xs:attribute name="id" type="xs:ID" use="required"/> 

方法のみunique XML identifiersid属性の値として許可されていること。ただし、有効なXML識別子は数字で始めることはできません。そのため、IDのタイプをid-1などに変更する必要があります。

関連する問題