Did you wonder or even struggle with these attributes elementFormDefault="qualified" and attributeFormDefault="unqualified" on the root element of an XML Schema?
Maybe you even ignored them without even paying attention on them, but still curious?
Well if you did, take a deep breath, this is the place to be and read on.

What is an XML namespace?

“XML namespaces are used for providing uniquely named elements and attributes in an XML document. They are defined in a W3C recommendation. An XML instance may contain element or attribute names from more than one XML vocabulary. If each vocabulary is given a namespace, the ambiguity between identically named elements or attributes can be resolved.”
See Wikipedia for more detailed info.

You can find a good XML namespace tutorial with nice examples on zvon.org.

A Schema without target namespace

Let’s first start with a schema without a target namespace. The target namespace is the place were your declared elements and attributes in your schema belong to.
So in this first example, the elements (A, B, C, D) and attributes (E, F) are not part of any namespace.
The elements (schema, element, complexType, sequence, …) of the schema itself belong to the namespace http://www.w3.org/2001/XMLSchema.
The prefix xs is used to refer to this namespace, but you can use whatever prefix you want as long as your namespace declaration has the same prefix.

schema without target namespace
  1. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  2.  <!– atts elementFormDefault and attributeFormDefault are irrelvant
  3.          when no @targettNamespace is used –>
  4.  <xs:element name="A">
  5.   <xs:complexType>
  6.    <xs:sequence>
  7.     <xs:element name="B" type="xs:string"/>
  8.     <xs:element name="C" type="xs:string"/>
  9.     <xs:element ref="D"/>
  10.    </xs:sequence>
  11.    <xs:attribute name="E" type="xs:string"/>
  12.    <xs:attribute ref="F"/>
  13.   </xs:complexType>
  14.  </xs:element>
  15.  <xs:element name="D" type="xs:string"/>
  16.  <xs:attribute name="F" type="xs:string"/>
  17. </xs:schema>
A corresponding instance without a target namespace
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:noNamespaceSchemaLocation="mySchema.xsd"
  4. E="valueforAttE" F="valueforAttF">
  5.  <B/>
  6.  <C/>
  7.  <D/>
  8. </A>

The attribute xsi:noNamespaceSchemaLocation="mySchema.xsd" is in the http://www.w3.org/2001/XMLSchema-instance namespace and is used to refer to the schema. So this attribute is not part of your schema because it lives in its own namespace.

In this context it has no sense to use elementFormDefault="qualified" or elementFormDefault="unqualified" or attributeFormDefault="qualified" or attributeFormDefault="unqualified".
It will not harm, you can try all the 4 combinations, it will make no difference, if there is no target namespace.

The scope of @elementFormDefault and @attributeFormDefault in XML Schema

So these 2 attributes are only relevant if a target namespace is used AND ONLY for LOCAL declared attributes and LOCAL declared elements.
If a target namespace is used, GLOBAL declared attributes and GLOBAL declared values MUST be qualified.
Qualified means: “belongs to a namespace”.
Unqualified means: “not belonging to a namespace”.
Why MUST global declared elements and attributes always belong to a namespace if a target namespace is used (and so the choice qualified/unqualified is irrelevant)?
Because global means you can refer to them from an other namespace and so you need to mention to which namespace you refer.
If the combination of namespaces with different schemas is not clear, don’t worry I will post a seperate post on this matter.

@elementFormDefault=”qualified” and @attributeFormDefault=”unqualified”

  1. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:foo="http://www.foo.org/"
  2. targetNamespace="http://www.foo.org/" elementFormDefault="qualified"
  3. attributeFormDefault="unqualified">
  4.  <xs:element name="A">
  5.   <xs:complexType>
  6.    <xs:sequence>
  7.     <xs:element name="B" type="xs:string"/>
  8.     <xs:element name="C" type="xs:string"/>
  9.     <xs:element ref="foo:D"/>
  10.    </xs:sequence>
  11.    <xs:attribute name="E" type="xs:string"/>
  12.    <xs:attribute ref="foo:F"/>
  13.   </xs:complexType>
  14.  </xs:element>
  15.  <xs:element name="D" type="xs:string"/>
  16.  <xs:attribute name="F" type="xs:string"/>
  17. </xs:schema>

The elements A and D and the attribute F are global declared (child elements of the root element <schema>).
So if we refer to D and F in the schema we must use the namespace (by using its prefix foo).

Example 1
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5. E="valueforAttE" foo:F="valueforAttF">
  6.  <B/>
  7.  <C/>
  8.  <D/>
  9. </A>

The element names A, B, C, D reside in the http://www.foo.org/ namespace. They don’t need a prefix foo (but in this case giving them one is no problem, see example 2 and 3) because the default namespace, declared by xmlns is also http://www.foo.org/.
The E attribute is local declared and unqualified in the schema so in the document instance it has no namespace.
The F attribute is global declared and there is a target namespace http://www.foo.org/ in the schema, so in the document instance this attribute must have the prefix referring to that namespace. Attributes without a prefix don’t belong to any namespace, not even the default namespace.

Example 2 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5.  E="valueforAttE" foo:F="valueforAttF">
  6.     <!– removing the default namespace on the root element A will give an error –>
  7.  <B/>
  8.  <C/>
  9.  <D/>
  10. </foo:A>
Example 3 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.  xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  4.  E="valueforAttE" foo:F="valueforAttF">
  5.  <foo:B/>
  6.  <foo:C/>
  7.  <foo:D/>
  8. </foo:A>

@elementFormDefault=”qualified” and @attributeFormDefault=”qualified”

This means all local declared elements and attributes must belong to the target namespace.

  1. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:foo="http://www.foo.org/"
  2. targetNamespace="http://www.foo.org/" elementFormDefault="qualified"
  3. attributeFormDefault="qualified">
  4.  <xs:element name="A">
  5.   <xs:complexType>
  6.    <xs:sequence>
  7.     <xs:element name="B" type="xs:string"/>
  8.     <xs:element name="C" type="xs:string"/>
  9.     <xs:element ref="foo:D"/>
  10.    </xs:sequence>
  11.    <xs:attribute name="E" type="xs:string"/>
  12.    <xs:attribute ref="foo:F"/>
  13.   </xs:complexType>
  14.  </xs:element>
  15.  <xs:element name="D" type="xs:string"/>
  16.  <xs:attribute name="F" type="xs:string"/>
  17. </xs:schema>
Example 1
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5.  foo:E="valueforAttE" foo:F="valueforAttF">
  6.  <B/>
  7.  <C/>
  8.  <D/>
  9. </A>
Example 2 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5.  foo:E="valueforAttE" foo:F="valueforAttF">
  6.     <!– removing the default namespace on the root element A will give an error –>
  7.  <B/>
  8.  <C/>
  9.  <D/>
  10. </foo:A>
Example 3 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  4. foo:E="valueforAttE" foo:F="valueforAttF">
  5.  <foo:B/>
  6.  <foo:C/>
  7.  <foo:D/>
  8. </foo:A>

@elementFormDefault=”unqualified” and @attributeFormDefault=”unqualified”

This means all local declared elements and attributes must not belong to a namespace.

  1. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:foo="http://www.foo.org/"
  2. targetNamespace="http://www.foo.org/"
  3. elementFormDefault="unqualified" attributeFormDefault="unqualified">
  4.  <xs:element name="A">
  5.   <xs:complexType>
  6.    <xs:sequence>
  7.     <xs:element name="B" type="xs:string"/>
  8.     <xs:element name="C" type="xs:string"/>
  9.     <xs:element ref="foo:D"/>
  10.    </xs:sequence>
  11.    <xs:attribute name="E" type="xs:string"/>
  12.    <xs:attribute ref="foo:F"/>
  13.   </xs:complexType>
  14.  </xs:element>
  15.  <xs:element name="D" type="xs:string"/>
  16.  <xs:attribute name="F" type="xs:string"/>
  17. </xs:schema>

Element B and C are local declared in the schema so they don’t belong to any namespace hence xmlns="", otherwise they would be in the scope of the default namespace declared on the A element.

Example 1
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5. E="valueforAttE" foo:F="valueforAttF">
  6.  <B xmlns=""/>
  7.  <C xmlns=""/>
  8.  <D/>
  9. </A>
Example 2 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5. E="valueforAttE" foo:F="valueforAttF">
  6.  <B xmlns=""/>
  7.  <C xmlns=""/>
  8.  <D/>
  9. </foo:A>
Example 3 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5. E="valueforAttE" foo:F="valueforAttF">
  6.  <B/>
  7.  <C/>
  8.  <foo:D/>
  9. </foo:A>

In this third example, we don’t need to “unnamespace” element B and C because there is no default namespace in scope.

@elementFormDefault=”unqualified” and @attributeFormDefault=”qualified”

  1. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  2. xmlns:foo="http://www.foo.org/" targetNamespace="http://www.foo.org/"
  3. elementFormDefault="unqualified" attributeFormDefault="qualified">
  4.  <xs:element name="A">
  5.   <xs:complexType>
  6.    <xs:sequence>
  7.     <xs:element name="B" type="xs:string"/>
  8.     <xs:element name="C" type="xs:string"/>
  9.     <xs:element ref="foo:D"/>
  10.    </xs:sequence>
  11.    <xs:attribute name="E" type="xs:string"/>
  12.    <xs:attribute ref="foo:F"/>
  13.   </xs:complexType>
  14.  </xs:element>
  15.  <xs:element name="D" type="xs:string"/>
  16.  <xs:attribute name="F" type="xs:string"/>
  17. </xs:schema>
Example 1
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5. foo:E="valueforAttE" foo:F="valueforAttF">
  6.  <B xmlns=""/>
  7.  <C xmlns=""/>
  8.  <D/>
  9. </A>
Example 2 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/" xmlns="http://www.foo.org/"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5. foo:E="valueforAttE" foo:F="valueforAttF">
  6.  <B xmlns=""/>
  7.  <C xmlns=""/>
  8.  <D/>
  9. </foo:A>
Example 3 with same schema
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <foo:A xmlns:foo="http://www.foo.org/"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.foo.org/ mySchema.xsd"
  5. foo:E="valueforAttE" foo:F="valueforAttF">
  6.  <B/>
  7.  <C/>
  8.  <foo:D/>
  9. </foo:A>

Conclusion

Well this is it, if you read until here, I guess you learned something new.
All examples were tested and validated with Eclipse.

Rating 4.50 out of 5
[?]