C# - How to remove xmlns from XElement

后端 未结 3 1843
野趣味
野趣味 2020-12-20 17:10

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:

<
相关标签:
3条回答
  • 2020-12-20 17:55

    The accepted 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);
                }
            }
        } 
    
    0 讨论(0)
  • 2020-12-20 17:59

    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();
    
    0 讨论(0)
  • 2020-12-20 18:07

    You could use IsNamespaceDeclaration to detect which attribute is a namespace

    xelement.Attributes()
            .Where( e => e.IsNamespaceDeclaration)
            .Remove();
    
    0 讨论(0)
提交回复
热议问题