XML Namespaces and Prefixes

This entry may be useful to people confused by BizTalk's inclination to insert "ns0" into XML messages, or to anyone confused by XML Namespaces in general.

Someone once asked me why their XML document wasn't validating. They thought that it was because the schema was expecting messages with a default namespace of "uri:my-namespace" but the document they were validating instead defined all the nodes using a prefix of "ns0", with ns0 mapping to uri:my-namespace.

One of the biggest misunderstandings in XML is namespaces. There's absolutely no difference to an xml parser or to the interpretation of a document whether you use a prefix on every node, or a default namespace. Prefixes are only a syntactic abbreviation. In other words:

<mydoc xmlns="uri:my-namespace">
<subnode />
</mydoc>
(The default namespace on the root node flows into the child - there is no prefix on the subnode, so it uses the default namespace)

is identical to:

  <ns0:mydoc xmlns:ns0="uri:my-namespace">
<ns0:subnode xmlns:ns1="uri:my-namespace" />
</ns0:mydoc>
(The prefix ns0 maps to uri:my-namespace, and both nodes are marked with ns0. The ns1 is irrelevant as it’s not used anywhere)

and to:

<ns0:mydoc xmlns:ns0="uri:my-namespace">
<ns1:subnode xmlns:ns1="uri:my-namespace" />
</ns0:mydoc>
(No default namespace, but ns0 and ns1 both map to uri:my-namespace and hence have identical meaning)

And

<ns0:mydoc xmlns:ns0="uri:my-namespace">
<subnode xmlns="uri:my-namespace" />
</ns0:mydoc>

(ns0 is defined and used on the parent; the subnode uses a default namespace (which would also flow into subnode’s children if it had any)

In all of the cases above, the namespace of subNode is uri:my-namespace.

It turned out in the end that the problem was that the schema defined the namespace as "uri:my-namespace" but the result document was coming back with a namespace of "uri:my-namespace/" - the trailing slash being all important. Remember folks, namespaces are just strings - a trailing slash may not make a difference to most Internet browsers, but they do in XML Schema.

ElementFormDefault

As a bonus, a little note on elementFormDefault.

If in your schema you use elementFormDefault="qualified" then you can validate all of the documents above with a schema similar to (pseudo-code): 

<xs:schema targetNamespace="uri:my-namespace" elementFormDefault="qualified">
<xs:element name="myDoc">
<xs:complexType>
<xs:sequence>
<xs:element name="subnode" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

If you changed the elementFormDefault to "unqualified" then instead it would only look for the root element to be in the namespace, and child elements would be unqualified (in the empty namespace):

<ns0:mydoc xmlns:ns0="uri:my-namespace">
<subnode/>
</ns0:mydoc>

and  

<ns0:mydoc xmlns:ns0="uri:my-namespace">
<ns1:subnode xmlns:ns1=""/>
</ns0:mydoc>
(An explicitly empty prefixed namespace definition)

and

<ns0:mydoc xmlns:ns0="uri:my-namespace">
<subnode xmlns=""/>
</ns0:mydoc>
(An explicitly empty default namespace definition for the sub node, and its child nodes if it had any)

Written by Duncan Millard