Namespace "inheritance" and XmlSerializer

CraigBlog

Syndication

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.


Posted Aug 25 2004, 11:48 AM by craig-andera

Comments

Eric W. Bachtal wrote re: Namespace &quot;inheritance&quot; and XmlSerializer
on 08-25-2004 2:06 PM
I don't think it can be said that in your example XML the "outermost element is namespace qualified" but the other elements belong to "no namespace". In your example, the "blah" elements belong to their parent's namespace ("uri"), unless the "..." you show in each "blah" element overrides that (I'm guessing they don't).

I think what's happening, though I don't have time to verify it, is that your use of a namespace prefix on the parent means you have to do a little more work during deserialization (and serialization, assuming you except to generate XML like this programmatically instead of just by hand). Here's some info:

http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemxmlserializationxmlserializernamespacesclasstopic.asp

Eric W. Bachtal wrote re: Namespace &quot;inheritance&quot; and XmlSerializer
on 08-25-2004 10:16 PM
Oops. Now that I've gotten some food :-) and read your post a little closer, I see that you meant for the blah elements to have no namespace, as indicated in your first paragraph and by your providing their parent element with a prefixed namespace. The assumption and suggestion in my first response was just wrong.

You are quite correct that you have to explicitly clear the namespace on the Blahs member in the class in order for this to work.

This becomes even clearer after deserializing an instance of your second class, which should produce something like this:

<bar xmlns="uri">
<blah xmlns="" ... />
<blah xmlns="" ... />
</bar>

Which is the same as your original XML, but without the namespace prefix. Obviously, your version is easier to type by hand, which was your original point.

Sorry for the confusion!
Craig wrote re: Namespace &quot;inheritance&quot; and XmlSerializer
on 08-26-2004 4:35 AM
Don't sweat it: nothing I haven't done myself before. ;)
Keith Brown wrote re: Namespace &quot;inheritance&quot; and XmlSerializer
on 08-26-2004 6:03 AM
Just FYI, in XML Schema, there's a way of saying that you're using this style:

<xsd:schema elementFormDefault=unqualified ...

If you use this with XSD, it'll generate the classes like you are doing by hand.

I totally agree that unqualified elements are much cleaner.
Craig wrote re: Namespace &quot;inheritance&quot; and XmlSerializer
on 08-26-2004 7:17 AM
A good point. I should also note that I rarely write XSD schemas...I tend to just author classes using the XmlSerializer attributes directly. I rarely care about anything other than what the objects look like and what the XML looks like, and doing it this way means the things I have to remember are C# and straight XML things, rather than XSD things. Since I have to know C# and XML things anyway, this is less cognitive dissonance for me.

Of course, I'm the sort of guy that tends to blow off wizards and write just about everything by hand.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?