Click here to Skip to main content
15,443,631 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have an XMLdoc , the below is just a snippet

<APCS:ParameterList>
<APCS:ParameterGroup name="GROUP">
<APCS:ParameterGroup name="W1">
<APCS:Parameter name="BASE">1</APCS:Parameter>
<APCS:Parameter name="LOOP">4</APCS:Parameter>
<APCS:Parameter name="WIRE">-1</APCS:Parameter>
<APCS:Parameter name="THREAD">-1</APCS:Parameter>
</APCS:ParameterGroup>
</APCS:ParameterGroup>
</APCS:ParameterList>

I need to remove the APCS namespace and return the doc as below

<ParameterList>
<ParameterGroup name="GROUP">
<ParameterGroup name="W1">
<Parameter name="BASE">1</Parameter>
<Parameter name="LOOP">4</Parameter>
<Parameter name="WIRE">-1</Parameter>
<Parameter name="THREAD">-1</Parameter>
</ParameterGroup>
</ParameterGroup>
</ParameterList>

What I have tried:

I have helper methods that can remove the namespace, however this is also removing the number values i.e.
<Parameter name="BASE" />


The methods are below.

private static XmlElement changeNameSpaceRecursionHelper(XmlDocument doc, XmlElement fragment, string originalNamespace, string targetNamespace)
{
    string newElementNamespace = (fragment.NamespaceURI == originalNamespace ? targetNamespace : fragment.NamespaceURI);
    XmlElement newElement = doc.CreateElement(fragment.LocalName, newElementNamespace);

    foreach (XmlNode node in fragment.ChildNodes)
    {
        if (node is XmlElement)
        {
            newElement.AppendChild(changeNameSpaceRecursionHelper(doc, (XmlElement)node, originalNamespace, targetNamespace));
        }
    }

    foreach (XmlAttribute attr in fragment.Attributes)
    {
        string newAttributeNamespace = (attr.NamespaceURI == originalNamespace ? targetNamespace : attr.NamespaceURI);
        XmlAttribute newAttribute = doc.CreateAttribute(attr.LocalName, newAttributeNamespace);
        newAttribute.Value = attr.Value;
        newElement.Attributes.Append(newAttribute);
    }

    return newElement;
}

/// <summary>
/// Returns an Xml fragment with the namespace of all elements/attributes that belonged to originalNamespace changed to targetNamespace
/// <para>Note that any nodes other than Elements or their attributes will not be present in the returned fragment.</para>
/// </summary>
/// <param name="fragment">An XmlElement that is the root of the fragment to be processed</param>
/// <param name="originalNamespace">Namespace URI to be replaced.</param>
/// <param name="targetNamespace">Namespace URI to replace with.</param>
/// <returns>An Xml fragment with namespace replacement as required.</returns>
public static XmlElement ChangeNameSpace(XmlElement fragment, string originalNamespace, string targetNamespace)
{
    XmlDocument doc = new XmlDocument();
    return changeNameSpaceRecursionHelper(doc, fragment, originalNamespace, targetNamespace);
}
Posted
Updated 29-Jan-17 9:26am
v2

1 solution

Since you're replacing it in the entire XML document I'd go for this simple and readable approach:

C#
using System.Xml;
using System.Text.RegularExpressions;

public static class XMLExtensions
{
    public static void RemoveNamespace(this XmlDocument document, string @namespace) =>
        document.InnerXml = Regex.Replace(
            document.InnerXml,
            $@"(?<=\</|\<){@namespace}:", 
            "");
}


EDIT: Changed regex to catch only namespaces in tags in case some data is named APCS. Small fix in case of a non-greedy default setting.

EDIT2: The xmlns namespace is usually only included once but if you need to programmatically remove it as well this will do it:

C#
using System.Xml;
using System.Text.RegularExpressions;

public static class XMLExtensions
{
    public static void RemoveNamespace(this XmlDocument document, string @namespace) =>
        document.InnerXml = Regex.Replace(
            document.InnerXml,
            $@"((?<=\</|\<){@namespace}:|xmlns:{@namespace}=""[^""]+"")", 
            "");
}
 
Share this answer
 
v6
Comments
bmw318mt 30-Jan-17 1:47am     CRLF
Hi, thanks for this solution, in case I want to remove such element and its closing tag (I have another element named ParameterList) <ParameterList xmlns:APCS="urn:st-com:ST:FW2:APCS"> can this be done?
Jon McKee 30-Jan-17 2:08am    
Updated the solution =)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900