简体   繁体   中英

C# - How to remove xmlns from XElement

How can I remove the "xmlns" namespace from a XElement?

I tried: attributes.remove, xElement.Name.NameSpace.Remove(0), etc, etc. No success.

My xml:

<event xmlns="http://www.blablabla.com/bla" version="1.00">
  <retEvent version="1.00">
  </retEvent>
</event>

How can I accomplish this?

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

You could use IsNamespaceDeclaration to detect which attribute is a namespace

xelement.Attributes()
        .Where( e => e.IsNamespaceDeclaration)
        .Remove();

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM