How to remove xmlns attribute from XDocument?

2019-03-27 19:15发布

问题:

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?

回答1:

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));
}