When using XMLSerializer to create an XML string of a serialization of a class oXML in vb.net as follows:
Dim x As New Xml.Serialization.XmlSerializer(oXML.GetType, "urn:oecd:blah:blah")
Dim xmlns = New XmlSerializerNamespaces()
xmlns.Add(String.Empty, "urn:oecd:blah:blah")
xmlns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance")
xmlns.Add("sfa", "urn:oecd:blah:blah1")
xmlns.Add("iso", "urn:oecd:blah:blah2")
xmlns.Add("ftc", "urn:oecd:blah:blah")
Dim sw As New IO.StringWriter()
x.Serialize(sw, oXML, xmlns)
You will notice that I have repeated the addition of namespace "urn:oecd:blah:blah" as both an empty "default" namespace on the xmlns object and also in the definition of x As New Xml.Serialization.XmlSerializer.
The problem is that this particular namespace only ever gets rendered with a prefix of ftc and the default is not shown. If I comment out the addition of the ftc namespace, and run it again, then a default namespace is rendered correctly. Is there a way to tell the serializer that this namespace is used as default and also with a prefix of ftc? I am assuming it is because the namespace is used twice, both as default and also with a prefix that it is ignoring it?
XmlSerializer
has no defined behavior in the case of passing anXmlSerializerNamespaces
with two prefixes for identical namespaces. It could choose either prefix and the result would be semantically identical. Further, from the reference source for the class it appears the namespaces are stored in a hash table so their order is unpredictable. But since the XML would have the same meaning either way, the simplest thing for you to do is to not worry about it.If for some reason you must have duplicated namespaces in your XML, and must use the default prefix in preference to an equivalent named prefix for elements in that namespace, you could serialize to an
XDocument
then add the missing duplicates manually:And then use it like:
Example dotnetfiddle.
Now, in your case the default namespace was omitted in favor of a duplicated prefixed namespace. If for some reason
XmlSerializer
chose to do the opposite (and it's not documented which it will choose), then adding the missing named namespace at the end of the root document's namespace list would cause all elements to be written with the named prefix. That's because it turns out that, when writing anXElement
, name/namespace pairs are pushed onto a stack during serialization and so the lattermost is used. To work around this, you could adapt the code from XDocument Save Removing Node Prefixes and move the default prefix to the end of the attribute list rather than the beginning.