I've taken to writing much of my XML like this:
<foo:bar xmlns:foo="uri">
<blah ... />
<blah ... />
</foo:bar>
Which is to say, with an outermost element that's namespace qualified, but with all other elements belonging to no namespace. This is primarily laziness - I type a lot of XML by hand, and write a lot of XPath, and both are slightly easier with this sort of XML.
Where I got burned today was in trying to write a set of types that deserialize this XML. I started with this:
[XmlRoot("foo", Namespace="uri")]
public class Foo {
private BlahCollection blahs = new BlahCollection();
[XmlElement("blah")]
public BlahCollection Blahs {
get { return blahs; }
}
}
And I expected it would work just fine. But I was surprised to find that when I did the deserialization, I got zero blahs in the resulting collection, even though there were two in the file. After banging my head against this problem for quite some time, I finally realized I needed to do something like this:
[XmlRoot("foo", Namespace="uri")]
public class Foo {
private BlahCollection blahs = new BlahCollection();
[XmlElement("blah", Namespace="")]
public BlahCollection Blahs {
get { return blahs; }
}
}
Note that I'm explicitly setting the namespace to the empty string. Apparently, what was happening was that without this explicit command, the [XmlElement("blah")] attribute was assuming the Namespace value of the [XmlRoot] attribute above it. So at deserialization time, it was looking for an element called "blah" from the "uri" namespace, but finding one called "blah" that was from no namespace.
Although I know I'm nothing like the first person to come across this, it isn't called out in the docs in a way that was obvious to me, so I thought I'd mention it here.