Peter Stegnar Peter Stegnar - 1 month ago 13
C# Question

How to remove all namespaces from XML with C#?

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:

public interface IXMLUtils
{
string RemoveAllNamespaces(string xmlDocument);
}


Sample XML to remove NS from:

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<insert>
<offer xmlns="http://schema.peters.com/doc_353/1/Types">0174587</offer>
<type2 xmlns="http://schema.peters.com/doc_353/1/Types">014717</type2>
<supplier xmlns="http://schema.peters.com/doc_353/1/Types">019172</supplier>
<id_frame xmlns="http://schema.peters.com/doc_353/1/Types" />
<type3 xmlns="http://schema.peters.com/doc_353/1/Types">
<type2 />
<main>false</main>
</type3>
<status xmlns="http://schema.peters.com/doc_353/1/Types">Some state</status>
</insert>
</ArrayOfInserts>


After we call RemoveAllNamespaces(xmlWithLotOfNs), we should get:

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts>
<insert>
<offer >0174587</offer>
<type2 >014717</type2>
<supplier >019172</supplier>
<id_frame />
<type3 >
<type2 />
<main>false</main>
</type3>
<status >Some state</status>
</insert>
</ArrayOfInserts>


Preffered language of solution is C# on .NET 3.5 SP1.

Answer

Well, here is the final answer. I have used great Jimmy idea (which unfortunately is not complete itself) and complete recursion function to work properly.

Based on interface:

string RemoveAllNamespaces(string xmlDocument);

I represent here final clean and universal C# solution for removing XML namespaces:

//Implemented based on interface, not part of algorithm
public static string RemoveAllNamespaces(string xmlDocument)
{
    XElement xmlDocumentWithoutNs = RemoveAllNamespaces(XElement.Parse(xmlDocument));

    return xmlDocumentWithoutNs.ToString();
}

//Core recursion function
 private static XElement RemoveAllNamespaces(XElement xmlDocument)
    {
        if (!xmlDocument.HasElements)
        {
            XElement xElement = new XElement(xmlDocument.Name.LocalName);
            xElement.Value = xmlDocument.Value;

            foreach (XAttribute attribute in xmlDocument.Attributes())
                xElement.Add(attribute);

            return xElement;
        }
        return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
    }

It's working 100%, but I have not tested it much so it may not cover some special cases ... But it is good base to start.