02 February 2006

Software: XML Namespaces and Schemas

This error message from Altova's XMLSpy bit me while I was testing an XML Schema:

Unexpected element 'title' in element 'book'.  Expected: title

Here is the sample document:

<?xml version="1.0"?>
<book
  xmlns="bookSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="bookSchema book.xsd"
  >
  <title>Snoopy</title>
  <author>Charles Schulz</author>
</book>

And here is the schema:

<?xml version="1.0" ?>
<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="bookSchema"
>
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="author" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Since I wasn't making any headway with XMLSpy's validator, I tried xsv from the University of Edinburgh and I received a more meaningful error message:

element {bookSchema}:title not allowed here (1) in element {bookSchema}:book, expecting [{None}:title]:

It turns out that in the XML Schema, title is not by default in the bookSchema namespace (see Qualified Locals in XML Schema Primer). The solution is to either add elementFormDefault="qualified" into the schema and force all local elements into the namespace or ensure that only the root element is in the namespace (using <bk:book xmlns:bk="bookSchema">) while its descendants are not in any namespace.