If you worked with NHibernate mappings, you know very well about the namespace declarations on the root element: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">. We generate these mappings programmatically, and we naturally wondered how to remove the default xmlns:xsd and xmlns:xsi declarations that the XmlSerializer adds, and add the NHibernate URN in the mix. The recipe below outlines the three necessary steps.
Step 1
Suppress the xmlns:xsi andxmlns:xsd declarations that XmlSerializer creates by default.
var namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(t, writer, namespaces);
We now have a clean root element, free of any namespace declarations.
Step 2
Add the NHibernate namespace declaration. An overloaded constructor of XmlSerializer does the trick:
var namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
var serializer = new XmlSerializer(typeof(T), "urn:nhibernate-mapping-2.2");
serializer.Serialize(t, writer, namespaces);
We now get the namespace declaration, but with a namespace prefix. Besides, since that prefix is not then used on the elements inside the root, the resulting document is not correct. What we want is a default namespace declaration. (See XML Namespaces for a roadmap.)
Step 3
Remove the namespace prefix from the declaration (make it a default namespace declaration.)
var namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, "urn:nhibernate-mapping-2.2");
var serializer = new XmlSerializer(typeof(T), "urn:nhibernate-mapping-2.2");
serializer.Serialize(t, writer, namespaces);
The document is now consistent with the goal. A default namespace declaration associates the root element and all its child nodes with the desired URI.
What happens if you skip some of these steps? Some things will go wrong:
- If you don’t use the overloaded constructor in step 2, you get no namespace declarations on the
hibernate-mappingelement. - If you use the overloaded constructor, but not the namespaces collection in step 1, the NHibernate URN gets an XmlSerializer-assigned namespace alias. I got
xmlns:q1=urn:nhibernate-mapping-2.2". - And finally, if you don’t include the NHibernate URN with an empty alias, as I did in step 3, you get no namespace declarations on the
hibernate-mappingelement.
Comments 1
Hi Mihai,
Posted 25 Sep 2008 at 5:05 am ¶Thanks for this information as it saved me a lot of time.
I wasn’t using the overloaded constructor in Step 2 – easy one to miss!
Regards
Stewart
Trackbacks & Pingbacks 1
[...] public links >> xmlserializer XmlSerializer Namespaces First saved by lordsytar | 2 days ago Porting to Silverlight 2 Beta First saved by KrispeKreme [...]
Post a Comment
You must be logged in to post a comment.