c# -如何从XElement中移除xmlns

本文关键字:xmlns XElement | 更新日期: 2023-09-27 18:17:16

如何从XElement中删除xmlns命名空间?

我试过:attributes.remove, xElement.Name.NameSpace.Remove(0),等等。没有成功。

我的xml:

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

我怎样才能做到这一点?

c# -如何从XElement中移除xmlns

@octaviocc的答案不适合我,因为xelement.Attributes()是空的,它没有返回名称空间作为属性。

下面的命令将删除你的声明:

element.Name = element.Name.LocalName;

如果您想对您的元素和所有子元素递归地执行此操作,请使用以下命令:

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

我想对现有的答案进行扩展。具体来说,我想参考一个从XElement中删除名称空间的常见用例,即:能够以通常的方式使用Linq查询。

当标签包含名称空间时,必须在每个Linq查询中使用该名称空间作为XNamespace(如本答案所述),因此使用OP的xml,它将是:

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

但是通常,我们不希望每次都使用这个命名空间。所以我们需要删除它

现在,@octaviocc的建议确实从给定元素中删除了名称空间属性。但是,元素名仍然包含命名空间,因此通常的Linq查询将无法工作。

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
因此,我们需要使用@Sam Shiles的建议,但它可以简化(不需要递归):
private static void RemoveAllNamespaces(XElement xElement)
{
    foreach (var node in xElement.DescendantsAndSelf())
    {
        node.Name = node.Name.LocalName;
    }
}

如果需要使用XDocument:

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

现在它工作了:

var element = xelement.Descendants("retEvent")).SingleOrDefault();

您可以使用IsNamespaceDeclaration来检测哪个属性是名称空间

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