开发者

XML Schema keyref problems, possibly problem with recursive elements

开发者 https://www.devze.com 2023-02-27 07:12 出处:网络
Ok I\'ve been banging my head against this one so long, I think I\'ve damaged my brain so much I forgot Shakespeare. It\'s ok, I don\'t use him that much. Here\'s my problem.

Ok I've been banging my head against this one so long, I think I've damaged my brain so much I forgot Shakespeare. It's ok, I don't use him that much. Here's my problem.

I have a list of fruit at the top of an xml document. This is the "lookup table" so to speak.

I then build a menu system below. Each menu can have more menus, or a list of products. These products must correspond to the fruit at the top.

I have been able to confirm that the list of fruit is being populated, and can even get the keyref to validate one level of the menu. But I cannot get it to validate the whole menu tree. I have marked the locations I tried to run use keyref with <!-- KEY FAIL -->.

I'm using xmllint to validate. If I do any xpath's with // in them, I get "Cannot compile".

Here is the example 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>

Here is the xsd:

&开发者_如何学Pythonlt;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>


The selector is relative to its context, so with the keyRef inside Menu, the selector would the Product and the field within the selector is just .:

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

Your xs:key needs to be more like:

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

but I'm guessing you just didn't sanitize it for the example like the other parts.

0

精彩评论

暂无评论...
验证码 换一张
取 消