6

ブック エントリごとに一意の ID を指定する必要があるブックの XML スキーマを設計しようとしています。ただし、うまくいかないようです。以下は私が使用している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>

これで検証しようとしている 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>

これは正常に検証されていませんが、正常に検証されています (2 つのエントリに同じ ID を使用しました)。私は XML にかなり慣れていないので、誰かがここで間違っていることを指摘していただければ幸いです。

4

2 に答える 2

11

<xs:unique>を間違った場所に持っています。要素定義自体ではなく、要素が一意である必要がある祖先要素の定義内にある必要があります。次の例では、ブック ID を各棚内で一意にする必要がありますが、異なる棚で同じ ID を使用できます。BookBook

  <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 内のプレフィックスのない名前は常に「名前空間なし」を意味するためです。xmlns:tns="<target namespace URI>"要素に追加してからxs:schema、のセレクターを使用する必要がありますtns:Shelf/tns:Book

于 2013-02-15T11:18:38.620 に答える
3

ID 値として特に数字を使用する必要がありますか? そうでない場合、次の代わりに属性タイプxs:IDとして使用する可能性があります。idxs:string

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

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

于 2013-02-15T11:22:49.193 に答える