XML XSD: This element is not expected

When testing a patch for Gerbera I wanted to validate my configuration file, saw that the config2.xsd file was broken and decided to fix it.

The Gerbera configuration XML has two <container> tags with different meanings, attributes and children. The XML schema definition had two top-level <element name="container"> entries which was criticised by xmllint:

$ xmllint --noout --schema test.xsd data.xml
test.xsd:17: element element: Schemas parser error : Element '{http://www.w3.org/2001/XMLSchema}element': A global element declaration '{http://example.org/cw}container' does already exist.
WXS schema test.xsd failed to compile

This happened because the Gerbera config XSD does not use nested declarations but a long list of top-level elements, just like we know it from DTDs.

A solution to the problem is not to declare the second "container" tag but to only define its type, and reference that:

data.xml
<?xml version="1.0"?>
<container xmlns="http://example.org/cw">
    <resources>
        <order direction="asc"/>
        <container name="foo"/>
    </resources>
</container>
test.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://example.org/cw" targetNamespace="http://example.org/cw">
 
    <xs:element name="container">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="resources" minOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
    <xs:element name="resources">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="order" minOccurs="1"/>
                <xs:element name="container" type="resContainer" minOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
    <xs:element name="order">
        <xs:complexType>
            <xs:attribute name="direction" type="xs:string"/>
        </xs:complexType>
    </xs:element>
 
    <xs:complexType name="resContainer">
        <xs:attribute name="name"/>
    </xs:complexType>
</xs:schema>

Now xmllint gave a strange error:

$ xmllint --noout --schema test.xsd data.xml
data.xml:4: element container: Schemas validity error : Element '{http://example.org/cw}container': This element is not expected. Expected is ( container ).
data.xml fails to validate

It gets a namespaced <container> tag but wants a non-namespaced container! This problem does not happen with the <order> tag which is loaded into the <resources> tag with a ref="" - it only happens when the nested xsd:element uses a name="" attribute.

I did not find any solutions when searching for "xsd" "This element is not expected. Expected is one of" element "ref" "name" in DuckDuckGo and Google and already started to write a question on StackOverflow when its "Similar Questions" list showed Sub-elements and namespaces in XSD. One tiny but important comment told the solution:

Add elementFormDefault="qualified" to your schema element (<xsd:schema ...>) and you should be good to go.

mechanical_meat, Jun 22, 2009 at 21:22

And indeed this was it:

new test.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://example.org/cw" targetNamespace="http://example.org/cw"
    elementFormDefault="qualified">
...
$ xmllint --noout --schema test.xsd data.xml
data.xml validates

elementFormDefault?

The elementFormDefault attribute is documented in XSD primer: 3.2 Qualified Locals and "documented" in XSD Structures: 3.15.2 XML Representations of Schemas, but I would never have guessed that this is related to my problem. Which proves what is written in the criticism section of the XML Schema wikipedia page:

It is too complicated (the spec is several hundred pages in a very technical language), so it is hard to use by non-experts — but many non-experts need schemas to describe data formats. The W3C Recommendation itself is extremely difficult to read.

Written by Christian Weiske.

Comments? Please send an e-mail.