views:

68

answers:

2

The following XSD should validate that the favorite_fruit element's name attribute should only contain names of fruit in the fruits element. Here is the XSD:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  <xsd:complexType name="Fruit">
    <xsd:attribute name="name" type="xsd:string"/>
  </xsd:complexType>  

  <xsd:complexType name="FruitArray">
    <xsd:sequence>
      <xsd:element name="fruit" minOccurs="0" maxOccurs="unbounded" type="Fruit"/>
    </xsd:sequence>
  </xsd:complexType> 

  <xsd:element name="fruit_basket">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="fruits" minOccurs="1" maxOccurs="1" type="FruitArray"/>
        <xsd:element name="favourite_fruit" minOccurs="1" maxOccurs="1">
          <xsd:complexType>
            <xsd:attribute name="name" use="required"/>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType> 

    <xsd:key name="fruit_lookup">
      <xsd:selector xpath="fruits/fruit"/>
      <xsd:field xpath="@name"/>
    </xsd:key>

    <xsd:keyref name="favourite_fruit_constraint" refer="fruit_lookup">
      <xsd:selector xpath="favourite_fruit"/>
      <xsd:field xpath="@name"/>
    </xsd:keyref>    
  </xsd:element>
</xsd:schema>

The following xml should be valid but when validated is invalid:

<fruit_basket>
  <fruits>
    <fruit name="Apple"/>
    <fruit name="Peach"/>
    <fruit name="Bananna"/>
  </fruits>

  <favourite_fruit name="Apple"/>
</fruit_basket>

Any ideas? My gut feels is that there is something wrong with my xpath. PS: I am using lxml to validate the xml against the xsd.

A: 

You have not given a type to the xsd:element of favourite_fruit. So the schema cannot validate against the type Fruit:

    <xsd:element name="favourite_fruit" minOccurs="1" maxOccurs="1">
      <xsd:complexType>
        <xsd:attribute name="name" use="required"/>
      </xsd:complexType>
    </xsd:element>

Nowhere are you constraining the type to be a Fruit. This should work better:

   <xsd:element name="favourite_fruit" minOccurs="1" maxOccurs="1" Type="Fruit" />
Oded
There is no need for a named type there, it's an anonymous, nested complex type.
skaffman
Which he wants to validate against his Type.
Oded
No actually I only want to validate that the name attribute of my anonymous type is equal to one of the names of the fruit types in the fruits array.
Johan
+1  A: 

The anonymous complex type specifies a attribute 'name' without a type. The Fruit type has a attribute 'name' with a type of : xsd:string. Because the two attributes doesn't have the same type they can't match. Thus changing the anonymous complex type attribute definition to : works.

Caz