16

In my C# codebase, I have an XDocument of the form:

<A>
 <B>
   <C xmlns='blabla' yz='blablaaa'> Hi </C>
   <D xmlns='blabla' yz='blablaaa'> How </D>
   <E xmlns='blabla' yz='blablaaa'> Are </E>
   <F xmlns='blabla' yz='blablaaa'> You </F>
 </B>
 <B>
   <C xmlns='blabla' yz='blablaaa'> I </C>
   <D xmlns='blabla' yz='blablaaa'> am</D>
   <E xmlns='blabla' yz='blablaaa'> fine</E>
    <F xmlns='blabla' yz='blablaaa'> thanks</F>
 </B>

Using Linq-to-XML or otherwise, I wanted to remove the xmlns for all the elements contained by element B.

Using the methodology given here: How to Remove specific attributes in XMLDocument?, I was able to remove all attributes except xmlns

What is the best way to remove 'xmlns' attribute from XDocument?

Community
  • 1
  • 1
GilliVilla
  • 4,998
  • 11
  • 55
  • 96
  • possible duplicate of [How to remove all namespaces from XML with C#?](http://stackoverflow.com/questions/987135/how-to-remove-all-namespaces-from-xml-with-c) – BrokenGlass Aug 09 '11 at 23:48
  • Why do you want to? Those aren't normal attributes. They define the namespace. – John Saunders Aug 10 '11 at 00:22
  • 1
    This is not a duplicate. And the accepted answer is much cleaner than what is claimed by the 'possible' duplicate. – GilliVilla Aug 11 '11 at 05:57

1 Answers1

23

It seems the namespace information are kept in two places in the object tree that represents the XML document in LINQ to XML: as actual xmlns attributes and inside the elements' Names. If you remove it from both places it's gone:

doc.Descendants()
   .Attributes()
   .Where( x => x.IsNamespaceDeclaration )
   .Remove();

foreach (var elem in doc.Descendants())
    elem.Name = elem.Name.LocalName;

(The first part of the code above is copied from now deleted answer by Bertrand Marron.)

If you wanted to remove namespaces from attributes too, that's little more complicated, because their Name is read-only:

foreach (var attr in doc.Descendants().Attributes())
{
    var elem = attr.Parent;
    attr.Remove();
    elem.Add(new XAttribute(attr.Name.LocalName, attr.Value));
}
svick
  • 236,525
  • 50
  • 385
  • 514
  • 1
    So actually the `XmlDocument` class does not have a member `.Descendants()`. My guess is that this code is for `XDocument` class which is not what is asked by OP. – supertopi Apr 06 '17 at 10:42
  • @supertopi The question explicitly asked for LINQ to XML, which is what this answer uses. But yes, that means it's `XDocument`, not `XmlDocument`. – svick Apr 06 '17 at 10:52
  • Ok, the title is a little misleading :) I will propose a modification – supertopi Apr 06 '17 at 11:04
  • You can type cast xmlDocument to xDocument easily to apply LINQ – Ashok Mandial Dec 17 '18 at 04:26
  • public static class DocumentExtensions { public static XmlDocument ToXmlDocument(this XDocument xDocument) { var xmlDocument = new XmlDocument(); using(var xmlReader = xDocument.CreateReader()) { xmlDocument.Load(xmlReader); } return xmlDocument; } } – Ashok Mandial Dec 17 '18 at 04:26