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.

Answer from Peter Stegnar on Stack Overflow
Top answer
1 of 16
122

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.

2 of 16
68

The tagged most useful answer has two flaws:

  • It ignores attributes
  • It doesn't work with "mixed mode" elements

Here is my take on this:

 public static XElement RemoveAllNamespaces(XElement e)
 {
    return new XElement(e.Name.LocalName,
      (from n in e.Nodes()
        select ((n is XElement) ? RemoveAllNamespaces(n as XElement) : n)),
          (e.HasAttributes) ? 
            (from a in e.Attributes() 
               where (!a.IsNamespaceDeclaration)  
               select new XAttribute(a.Name.LocalName, a.Value)) : null);
  }          

Sample code here.

🌐
Microsoft Learn
learn.microsoft.com › en-us › answers › questions › 857792 › how-to-remove-the-xmlns-attribute-that-gets-added
how to remove the xmlns attribute that gets added by the xmldocument - Microsoft Q&A
May 20, 2022 - newElem = xmlDocument.CreateNode("element", "newnode", ""); //creates the node newElem.InnerText ="test" ; nodeList[0].AppendChild(newElem); //appends the node string data = xmlDocument.OuterXml; //while assiging the xmldocument to a string variable , its adding attribute xmlns="" to the newnode added
Discussions

c# - Remove xmlns attribute from xml - Stack Overflow
In below Xml, I tried to delete the xmlns attribute but, its unable to populate under, xmlNode.Attributes still appear under OuterXml and final XmlDocument. ... More on stackoverflow.com
🌐 stackoverflow.com
c# - How to remove xmlns attribute of a node other than root in an XDocument? - Stack Overflow
Situation I'm using XDocument to try and remove an xmlns="" attribute on the first inner node: More on stackoverflow.com
🌐 stackoverflow.com
Remove all namespace attributes from xml using xmlstarlet - Unix & Linux Stack Exchange
I want to remove all the namespace attributes from the following XML. I have tried to remove ... More on unix.stackexchange.com
🌐 unix.stackexchange.com
xml - C# - How to remove xmlns from XElement - Stack Overflow
Kept getting the error: The prefix ... I tried every damn thing I could find in the internet ... It didn't work man! The xmlns was not recognized was a namespace. ... Nothing happens @octavioccl. xelement is the same before and after the Attributes("xmlns").Remove()... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › dotnet › sdk › issues › 16869
How to remove System.Xml.XmlElement (not XElement) Outerxml xmlns? · Issue #16869 · dotnet/sdk
April 13, 2021 - void Main() { var doc = new XmlDocument(); doc.LoadXml(xml); XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable); ns.AddNamespace("x", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); var dimension = doc.SelectSingleNode("/x:worksheet/x:dimension",ns) as XmlElement; Console.WriteLine(dimension.OuterXml); } // You can define other methods, fields, classes and namespaces here const string xml = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?> <worksheet xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:r=""http://schemas.openxmlform
Author   shps951023
Top answer
1 of 2
42

I think the code below is what you want. You need to put each element into the right namespace, and remove any xmlns='' attributes for the affected elements. The latter part is required as otherwise LINQ to XML basically tries to leave you with an element of

Copy<!-- This would be invalid -->
<Firstelement xmlns="" xmlns="http://my.namespace">

Here's the code:

Copyusing System;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        XDocument doc = XDocument.Load("test.xml");
        // All elements with an empty namespace...
        foreach (var node in doc.Root.Descendants()
                                .Where(n => n.Name.NamespaceName == ""))
        {
             // Remove the xmlns='' attribute. Note the use of
             // Attributes rather than Attribute, in case the
             // attribute doesn't exist (which it might not if we'd
             // created the document "manually" instead of loading
             // it from a file.)
             node.Attributes("xmlns").Remove();
             // Inherit the parent namespace instead
             node.Name = node.Parent.Name.Namespace + node.Name.LocalName;
        }
        Console.WriteLine(doc); // Or doc.Save(...)
    }
}
2 of 2
23

There is no need to 'remove' the empty xmlns attribute. The whole reason that the empty xmlns attrib is added is because the namespace of your childnodes is empty (= '') and therefore differ from your root node. Adding the same namespace to your childs as well will solve this 'side-effect'.

CopyXNamespace xmlns = XNamespace.Get("http://my.namespace");

// wrong
var doc = new XElement(xmlns + "Root", new XElement("Firstelement"));

// gives:
<Root xmlns="http://my.namespace">
    <Firstelement xmlns="" />
</Root>

// right
var doc = new XElement(xmlns + "Root", new XElement(xmlns + "Firstelement"));

// gives:
<Root xmlns="http://my.namespace">
    <Firstelement />
</Root>
Top answer
1 of 2
2

I have found a couple of XSLT solutions to do this, both of which can conveniently be processed with xmlstarlet:

  1. How to remove the namespace and its prefixes in an XML file using XSLT? - IBM
  2. XSLT: Remove namespace prefix from elements - StackOverflow

In my worked example below, I've used the IBM code and saved it into the file xslt_ibm:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <!-- https://www.ibm.com/support/pages/how-remove-namespace-and-its-prefixes-xml-file-using-xslt -->
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/|comment()|processing-instruction()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

If you consider your XML file to be saved in the file file.xml then this command will rename each element and attribute out of its namespace:

xmlstarlet transform xslt_ibm file.xml

Input (file.xml)

<md:EntityDescriptor xmlns="urn:_" xmlns:md="_"></md:EntityDescriptor>

Output

<?xml version="1.0"?>
<EntityDescriptor/>
2 of 2
0

Using Andrey Kislyuk's xq, an XML-parsing wrapper around jq (installed together with yq):

xq -x 'walk(del( .["@xmlns"]?, .["@xmlns:md"]? ))' file

This walks all nodes in the XML document structure and deletes all xmlns and xmlns:md attributes wherever these are found.

Given some input document,

<?xml version="1.0"?>
<root test="val">
  <md:EntityDescriptor xmlns="urn:_" xmlns:md="_"/>
</root>

... this would output

<root test="val">
  <md:EntityDescriptor></md:EntityDescriptor>
</root>

You get in-place editing with the --in-place or -i option.

🌐
W3Schools
w3schools.com › xml › met_element_removeattributens.asp
XML DOM removeAttributeNS() Method
DOM Node Types DOM Node DOM NodeList DOM NamedNodeMap DOM Document DOM Element DOM Attribute DOM Text DOM CDATA DOM Comment DOM XMLHttpRequest DOM Parser XSLT Elements XSLT/XPath Functions ... The following code fragment loads "books_ns.xml" into xmlDoc and removes the "lang" attribute from the first <title> element:
Find elsewhere
Top answer
1 of 3
14

I'd like to expand upon the existing answers. Specifically, I'd like to refer to a common use-case for removing namespaces from an XElement, which is: to be able to use Linq queries in the usual way.

When a tag contains a namespace, one has to use this namespace as an XNamespace on every Linq query (as explained in this answer), so that with the OP's xml, it would be:

XNamespace ns = "http://www.blablabla.com/bla";
var element = xelement.Descendants(ns + "retEvent")).Single();

But usually, we don't want to use this namespace every time. So we need to remove it.

Now, @octaviocc's suggestion does remove the namespace attribute from a given element. However, the element name still contains that namespace, so that the usual Linq queries won't work.

Console.WriteLine(xelement.Attributes().Count()); // prints 1
xelement.Attributes().Where( e => e.IsNamespaceDeclaration).Remove();
Console.WriteLine(xelement.Attributes().Count()); // prints 0
Console.WriteLine(xelement.Name.Namespace); // prints "http://www.blablabla.com/bla"
XNamespace ns = "http://www.blablabla.com/bla";
var element1 = xelement.Descendants(ns + "retEvent")).SingleOrDefault(); // works
var element2 = xelement.Descendants("retEvent")).SingleOrDefault();      // returns null

Thus, we need to use @Sam Shiles suggestion, but it can be simplified (no need for recursion):

private static void RemoveAllNamespaces(XElement xElement)
{
    foreach (var node in xElement.DescendantsAndSelf())
    {
        node.Name = node.Name.LocalName;
    }
}

And if one needs to use an XDocument:

private static void RemoveAllNamespaces(XDocument xDoc)
{
    foreach (var node in xDoc.Root.DescendantsAndSelf())
    {
        node.Name = node.Name.LocalName;
    }
}

And now it works:

var element = xelement.Descendants("retEvent")).SingleOrDefault();
2 of 3
11

@octaviocc's answer did not work for me because xelement.Attributes() was empty, it wasn't returning the namespace as an attribute.

The following will remove the declaration in your case:

element.Name = element.Name.LocalName;

If you want to do it recursively for your element and all child elements use the following:

    private static void RemoveAllNamespaces(XElement element)
    {
        element.Name = element.Name.LocalName;

        foreach (var node in element.DescendantNodes())
        {
            var xElement = node as XElement;
            if (xElement != null)
            {
                RemoveAllNamespaces(xElement);
            }
        }
    } 
🌐
The Coding Forums
thecodingforums.com › archive › archive › xml
How to remove xmlns attribute from XML document (.net) | XML | Coding Forums
May 8, 2006 - If you want to remove a namespace by processing the document as XML it's going to be tedious, since you're changing all the elements to be in a different namespace. You can't just remove the attribute unless there's some way to disable namespace processing, because once you've parsed the file it has already had its effect on all the other elements. -- Richard ... 1. Read the file 2. look for xmlns="..." 3.
🌐
Post.Byes
post.bytes.com › home › forum › topic › c sharp
How to remove xmlns attribute from XML document (.net) - Post.Byes
May 6, 2006 - > > I just would like to know if we can programmaticall y remove the > namespace to make the data (XML) file loadable. > > Frank >[/color] What's your schema file? The namespace in the schema should match the document. You can probably make it work by setting the namespace in the schema. ... Re: How to remove xmlns attribute from XML document (.net) What's weird is that the particular namespace is not in the schema file.
🌐
Google Groups
groups.google.com › g › xslt › c › tlA1FCMkfsc
How to remove "xmlns" attribute when calling a named template
I noticed you're not declaring a default namespace for this transformation, meaning the output default namespace is null or xmlns="". Your code defines the namespace xmlns="somexmlns" as the namespace for the request element. If your test element was defined inside the same template as the one containing the request element the processor would assume the test element would be using the same namespace as the request element, but because you have placed the test element in a separate template the processor thinks your test element is using the default namespace.
🌐
Dynamics Community
community.dynamics.com › forums › thread › details
How to remove XML Attributes from code?
How can I remove attributes from XML nodes using code · I tried xmlElement.removeAttribute('atrributeName'); and also removeAllAtribute(); but when file is generated the attributes are still there
🌐
Oracle
asktom.oracle.com › pls › apex › f
XML file removing namespaces in attributes - Ask TOM - Oracle
September 30, 2021 - XML file removing namespaces in attributes Hello Tom & Team,Greetings to All of you!!!My query is in continuation w.r.t to an earlier question asked in the forum.'removing attribute from very large xml' date October 04, 2019 - 12:10 pm UTC.In this you have mentioned how to remove namespaces ...
🌐
IBM
ibm.com › support › pages › how-do-you-remove-xmlns-attribute-output-root-element-generated-map
How do you remove the xmlns attribute from the output root element generated by a map?
July 16, 2018 - If you do not want the xmlns attribute ... Property > Schema > Type > Metadata > Name Spaces > http://www.example.com/IPO · After right clicking on http://www.example.com/IPO, left click on Delete ......
🌐
Stack Overflow
stackoverflow.com › questions › 79085968 › remove-xmlns-from-element-which-has-no-attributes
c# - Remove XMLNS from element which has no attributes - Stack Overflow
<siblingNode>data</siblingNode> <newNode xmlns=""></newNode> I have tried everything I can think of to remove this: newNode.Attributes().Remove() // The new node's attributes are null, so this won't work.