First of all - there is no difference between mentioned versions of XML for compliant XML parser. It does not really matter if/how/where namespace prefixes defined as long as nodes have correct namespaces associated.
As this question is explicitly about style where to put namespace declaration one makes own call what is nice and what is not. In this particular case goal is to avoid duplicated xmlns
attributes and move them higher in the tree.
One can write xmlns attributes wherever needed as long they don't conflict on the same node. Use XmlWriter.WriteAttributeString method to add them:
writer.WriteAttributeString(
"xmlns", "prefix", null, "urn:mynamespace");
To avoid duplicate declarations - check if prefix already defined for given namespace using XmlWriter.LookupPrefix
Sample code to ensure xsd
and xsi
prefixes (by Vlad):
const string xsiNamespace = System.Xml.Schema.XmlSchema.InstanceNamespace;
const string xsdNamespace = System.Xml.Schema.XmlSchema.Namespace;
public static void EnsureDefaultNamespaces(System.Xml.XmlWriter writer)
{
if (writer.LookupPrefix(xsiNamespace) == null)
writer.WriteAttributeString("xmlns", "xsi", null, xsiNamespace);
if (writer.LookupPrefix(xsdNamespace) == null)
writer.WriteAttributeString("xmlns", "xsd", null, xsdNamespace);
}
Alternative approach if more changes desired to achieve nice looking XML is to allow serialization to finish and than process XML to adjust prefixes definitions (i.e. normalize to desired prefixes, collect all namespaces and define all on top). One can either read XML with C# code or even create XSLT transformation.