I am looking for the clean, elegant and smart solution to remove namespacees from all XML elements? How would function to do that look like?
Defined interface:
I know this question is supposedly solved, but I wasn't totally happy with the way it was implemented. I found another source over here on the MSDN blogs that has an overridden XmlTextWriter class that strips out the namespaces. I tweaked it a bit to get some other things I wanted in such as pretty formatting and preserving the root element. Here is what I have in my project at the moment.
http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx
///
/// Modified XML writer that writes (almost) no namespaces out with pretty formatting
///
///
public class XmlNoNamespaceWriter : XmlTextWriter
{
private bool _SkipAttribute = false;
private int _EncounteredNamespaceCount = 0;
public XmlNoNamespaceWriter(TextWriter writer)
: base(writer)
{
this.Formatting = System.Xml.Formatting.Indented;
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
base.WriteStartElement(null, localName, null);
}
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
//If the prefix or localname are "xmlns", don't write it.
//HOWEVER... if the 1st element (root?) has a namespace we will write it.
if ((prefix.CompareTo("xmlns") == 0
|| localName.CompareTo("xmlns") == 0)
&& _EncounteredNamespaceCount++ > 0)
{
_SkipAttribute = true;
}
else
{
base.WriteStartAttribute(null, localName, null);
}
}
public override void WriteString(string text)
{
//If we are writing an attribute, the text for the xmlns
//or xmlns:prefix declaration would occur here. Skip
//it if this is the case.
if (!_SkipAttribute)
{
base.WriteString(text);
}
}
public override void WriteEndAttribute()
{
//If we skipped the WriteStartAttribute call, we have to
//skip the WriteEndAttribute call as well or else the XmlWriter
//will have an invalid state.
if (!_SkipAttribute)
{
base.WriteEndAttribute();
}
//reset the boolean for the next attribute.
_SkipAttribute = false;
}
public override void WriteQualifiedName(string localName, string ns)
{
//Always write the qualified name using only the
//localname.
base.WriteQualifiedName(localName, null);
}
}
//Save the updated document using our modified (almost) no-namespace XML writer
using(StreamWriter sw = new StreamWriter(this.XmlDocumentPath))
using(XmlNoNamespaceWriter xw = new XmlNoNamespaceWriter(sw))
{
//This variable is of type `XmlDocument`
this.XmlDocumentRoot.Save(xw);
}