Here we are in the year 2005. XML has been pretty ubiquitous for at least 5–6 years now. Namespaces have been in use for pretty much all of that time. And yet they remain possibly the least understood part of average, everyday XML processing.
The bottom line is that pretty much any XML parser worth its salt these days supports the namespaces spec. Which means that
is absolutely not the same thing as
Furthermore, in line with the XML Namespaces spec, an application which is expecting the latter, namespace qualified element should not and must not process the former, unqualified element.
The XmlSerializer that we all know and love in .NET is particularly sensitive to this issue (as well it should be). As far as the serializer is concerned, everything should be namespace qualified. The way this commonly bites people is thus: a customer/partner sends you a schema representing the XML documents they are going to be sending you. In the schema, the targetNamespace attribute is set with a value of “http://partner.com/schema”. When you actually do to debug the application however, it turns out they are sending you totally unqualified XML. Nothing will work. There are a few pretty horrible things you can do with the XmlSerializer to try and convince it not to be such a stickler about things, most involving the XmlRootAttribute and XmlAttributeOverrides. I can share those ways if anyone really wants to see them. Probably best to keep them under cover. However, that’s only likely to work if your XML document is flat, meaning that the root element only has one level of child nodes under it. Otherwise, if you use Xsd.exe to generate your serialization class, each set of sub elements get put in their own object, which will also be namespace qualified. And you’re back to square one.
The right solution of course is to get your partner to send you XML that’s actually correct, but often that’s just not possible for a variety of reasons with which I’m sure we’re all familiar. As a last ditch effort, you can pre-process the XML text before passing it to the XmlSerializer, and inject the right namespace strings. Yucky, it’s true, but it does actually get the job done. You will of course, be paying some overhead costs of string processing and possibly parsing the XML twice. But what can you do?
The other thing to keep in mind is how namespaces play out in XSD schema files. You can only have one target namespace per schema, so anything you define in that schema file will be in that target namespace. You can import things from other namespaces, but not from the target namespace. You can, however, define two different schema files that use the same namespace, then import them both into another schema, as long as there are no name collisions. If you omit the targetNamespace attribute from your schema, the targetNamespace becomes “”, meaning you are defining the schema for an unqualified XML document.
Confusing enough? Read the namespace spec (it’s really short), familiarize yourself with how namespaces work in schema, if you see errors coming back from the XmlSerializer that look like
The element <spam xmlns=””> was not expected.
check your namespaces! That means you are trying to deserialize an unqualified document, when a qualified one was expected.