2011-04-19 60 views
1

好吧,我一直在對這個問題喋喋不休,我覺得我已經損傷了我的大腦,所以我忘了莎士比亞。沒關係,我不會那麼用他。這是我的問題。XML Schema keyref問題,可能是遞歸元素的問題

我有一個XML文檔頂部的水果列表。可以這麼說,這是「查找表」。

然後我在下面建立一個菜單系統。每個菜單可以有更多的菜單或產品列表。這些產品必須符合頂部的水果。

我已經能夠確認正在填充水果列表,甚至可以獲取keyref來驗證菜單的一個級別。但我無法得到它來驗證整個菜單樹。我用<!-- KEY FAIL -->標記了我嘗試使用keyref的位置。

我正在使用xmllint進行驗證。如果我用//在其中執行任何xpath,我會得到「無法編譯」。

下面是示例XML:

<Snarf xmlns="" xsi:noNamespaceSchemaLocation="mySchema.xsd" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Fruit name="apple" /> 
    <Fruit name="orange" /> 
    <Fruit name="watermelon" /> 

    <Blarg> 
     <Menu name="Top Menu"> 
      <Menu name="Skillz"> 
       <Menu name="Juizy"> 
        <Product>orange</Product> 
        <Product>watermelon</Product> 
       </Menu> 
       <Menu name="nutty"> 
        <Product>orange</Product> 
       </Menu> 
      </Menu> 
      <Menu name="Applz"> 
       <Product>apple</Product> 
      </Menu> 
     </Menu> 
    </Blarg> 
</Snarf> 

這裏是XSD:

<xs:complexType name="productmenu"> 
<xs:choice minOccurs="1" maxOccurs="1"> 
    <xs:choice minOccurs="1" maxOccurs="unbounded"> 
     <xs:element name="Menu" type="productmenu"> 
      <!-- KEY FAIL --> 
      <!-- <xs:keyref name="subMenuProductRef" refer="productNumber"> 
       <xs:selector xpath="Menu"/> 
       <xs:field xpath="Product"/> 
      </xs:keyref> --> 
     </xs:element> 
    </xs:choice> 
    <xs:choice minOccurs="1" maxOccurs="unbounded"> 
     <xs:element name="Product" type="xs:integer" 
      minOccurs="1" maxOccurs="unbounded"/> 
    </xs:choice> 
</xs:choice> 
<xs:attribute name="name" type="xs:string" use="required" /> 
</xs:complexType> 

<xs:element name="Snarf"> 
    <xs:complexType> 
     <xs:choice minOccurs="0" maxOccurs="unbounded"> 

<xs:element name="Fruit" maxOccurs="unbounded" minOccurs="1" type="string"/> 

<xs:element name="Blarg" maxOccurs="unbounded" minOccurs="0"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="Menu" type="productmenu" 
       maxOccurs="unbounded" minOccurs="1"> 

       <!-- KEY FAIL --> 
       <!-- <xs:keyref name="subMenuProductRef" refer="productNumber"> 
        <xs:selector xpath="Menu"/> 
        <xs:field xpath="Product"/> 
       </xs:keyref>--> 
      </xs:element> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" use="required" /> 
    </xs:complexType> 

    <!-- KEY FAIL --> 
    <!-- <xs:keyref name="menuProductRef" refer="productNumber"> 
     <xs:selector xpath="Menu"/> 
     <xs:field xpath="Product"/> 
    </xs:keyref> --> 
</xs:element> 

     </xs:choice> 
    </xs:complexType> 

    <xs:key name="productNumber"> 
     <xs:selector xpath="./Product"/> 
     <xs:field xpath="@num"/> 
    </xs:key> 
    <!-- KEY FAIL --> 
    <!-- <xs:keyref name="menuProductRef" refer="productNumber"> 
     <xs:selector xpath="./Blarg/Menu"/> 
     <xs:field xpath="Product"/> 
    </xs:keyref> --> 
</xs:element> 

回答

0

選擇器是相對於它的上下文,所以用keyRef內部Menu,選擇器將所述Product和選擇器內的字段僅爲.

<xs:element name="Menu" type="productmenu"> 
    <xs:keyref name="subMenuProductRef" refer="productNumber"> 
     <xs:selector xpath="Product"/> 
     <xs:field xpath="."/> 
    </xs:keyref> 
</xs:element> 

xs:key需要更多這樣的:

<xs:key name="productNumber"> 
    <xs:selector xpath="./Fruit"/> 
    <xs:field xpath="@name"/> 
</xs:key> 

,但我猜你只是沒有清理它的其他部件一樣的例子。

+0

對不起,我不得不在同時移動到其他項目。我檢查了你的方法看起來不錯。但是我仍然沒有獲得我想要的功能。無論如何,我正在給它支票,只是基於它使我更接近答案。這和我不知道我是否有時間去充分檢查。謝謝您的幫助! – decoy 2011-05-31 20:42:49