2010-05-19 25 views
6

Tôi làm việc với một số tệp XML một cách thường xuyên và muốn có xác thực tốt hơn thì DTD có thể cung cấp. Vì vậy, tôi bắt đầu đọc về các lược đồ để xem liệu tôi có thể giúp tôi không. Cho đến nay tôi đã có thể tạo ra một thứ gì đó hoạt động gần giống như tôi cần trừ một phần. Tôi muốn có thể hạn chế thuộc tính của một phần tử với các giá trị của một thuộc tính khác nhau của các phần tử anh chị em hoặc tổ tiên có cùng loại phần tử. Thậm chí điều này có thể xảy ra với các ràng buộc khóa/lược đồ XML không?Cách tạo lược đồ xml với khóa/keyref cho các phần tử lồng nhau cùng loại

Tôi đã có một tài liệu mà trông giống như sau:

<nodeContainer> 
    <node name="Table"> 
    </node> 

    <node name="MyHouse"> 
     <node name="RoomWithDoor"> 
     </node> 
     <node name="DiningRoom" extends="RoomWithDoor"> 
      <node name="DiningTable" extends="Table"> 
      </node> 
     </node> 
    </node> 

    <node name="MySummerHouse"> 
     <node name="DiningRoom"> 
      <node name="DiningTable" extends="Table"> 
      </node> 
     </node> 
    </node> 
</nodeContainer> 

Trong tài liệu này, các nút có thể "mở rộng" nút khác đó là:

  • anh chị em
  • anh chị em của cha mẹ

tuy nhiên, các nút không được "mở rộng":

  • cha mẹ
  • trẻ em nút của anh chị em của cha mẹ

Điều này có nghĩa rằng MyHouse có thể "mở rộng" Bảng, mà không có ý nghĩa, nhưng tôi vẫn ổn với điều đó.

Cũng quan trọng là cả hai nút nhà sẽ có thể có các nút riêng của mình có tên là DiningRoom.

Và schema hiện tại của tôi là tương tự như sau:

<xs:complexType name="node"> 
    <xs:choice minOccurs="0" maxOccurs="unbounded"> 
     <xs:element ref="node"/> <!-- node can have other nodes inside it --> 
     <xs:element ref="leaf"/> 
    </xs:choice> 
    <xs:attribute name="name"  type="xs:anySimpleType" use="required"/> 
    <xs:attribute name="extends" type="xs:anySimpleType"/> 
</xs:complexType> 

<!-- document root --> 
<xs:element name="root"> 
    <xs:complexType> 
     <xs:choice minOccurs="0" maxOccurs="unbounded"> 
      <xs:element name="nodeContainer"> 
       <xs:complexType> 
        <xs:choice minOccurs="0" maxOccurs="unbounded"> 
         <xs:element ref="node"/>  
        </xs:choice> 
       </xs:complexType> 
      </xs:element> 
      <xs:element ref="otherType"/> 
     </xs:choice> 
    </xs:complexType> 

    <!-- create constrictions --> 
    <xs:unique name="UniqueNodes"> 
     <xs:selector xpath="nodeContainer/node"/> 
     <xs:field xpath="@name"/> 
    </xs:unique> 
    <xs:keyref refer="UniqueNodes" name="ValidNodeExtends"> 
     <xs:selector xpath=".//node"></xs:selector> 
     <xs:field xpath="@extends"></xs:field> 
    </xs:keyref> 
</xs:element> 

schema này làm một phần của những gì tôi đang tìm kiếm. Nó đặt các khóa là tên của cấp độ đầu tiên của các nút trong nodeContainer và các khóa đó có thể được sử dụng để "mở rộng" bất kỳ nút nào ở bất kỳ cấp nào tại hoặc bên dưới nodeContainer. Và điều đó hoạt động miễn là tôi không muốn "mở rộng" anh chị em ở các cấp thấp hơn. Các tài liệu ví dụ trên không xác nhận vì dòng này:

<node name="DiningRoom" extends="RoomWithDoor"> 

Trong schema Tôi đã tạo RoomWithDoor không phải là một chìa khóa hợp lệ để gán cho "mở rộng" vì nó không phải là một phần của cấp độ đầu tiên của các nút trong số nodeContainer. Nhưng có anyway để viết các phím/keyrefs để làm cho họ khóa hợp lệ? Vị trí của các định nghĩa khóa/keyref có tạo nên sự khác biệt không? Là xpath của tôi quá cụ thể (làm thế nào họ có thể ít cụ thể hơn)?

Trả lời

0

Điều gì sẽ xảy ra nếu bạn thay đổi selector XPath cho UniqueNodes để

<xs:selector xpath="nodeContainer//node"/> 

Nói cách khác - bất kỳ yếu tố nút dưới nodeContainer. Điều này có cho phép những gì bạn muốn đạt được không?

Các vấn đề liên quan