C# - 如何从 XElement 中删除 xmlns

Posted

技术标签:

【中文标题】C# - 如何从 XElement 中删除 xmlns【英文标题】:C# - How to remove xmlns from XElement 【发布时间】:2016-11-09 22:49:43 【问题描述】:

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

我试过了:attributes.removexElement.Name.NameSpace.Remove(0) 等等。没有成功。

我的 xml:

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

我怎样才能做到这一点?

【问题讨论】:

你不能轻易做到这一点;这意味着将每个名称都重写为没有命名空间。你想解决什么问题?您应该始终如一地使用命名空间。 您是如何开始使用 XML 的?是您的代码创建它,还是您从其他地方读取的 XML?更多信息在这里会很有帮助。 SLaks,问题是当命名空间存在于某些节点时,我的架构没有验证。 我正在从数据库 Jon 中读取一个 varchar。首先,我将其解析为 XDocument e,然后将其解析为 XElement "XDocument.Descendants().Where(p => p.Name.LocalName == "event").FirstOrDefault()" 【参考方案1】:

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

【讨论】:

不断收到错误:前缀 '' 不能从 '' 重新定义到同一起始元素标记内。只是对现有文档中的一个元素使用了简单的形式,即使我尝试从文档中单独复制元素,然后使用“element.Name = element.Name.LocalName;”并将其附加到文档中,不断出现错误,在我尝试了我在互联网上找到的所有该死的东西之后,只有另一个答案才有效 Arf,它是 xml...世界继续前进是有原因的 :)【参考方案2】:

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

当标签包含命名空间时,必须在每个 Linq 查询 (as explained in this answer) 上将此命名空间用作 XNamespace,这样对于 OP 的 xml,它将是:

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

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

现在,@octaviocc 的建议确实从给定元素中删除了命名空间 attribute。但是,元素名称仍然包含该命名空间,因此通常的 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();

【讨论】:

太棒了!感谢您的贡献。 对不起我的朋友!再次感谢。 使用 void 函数是愚蠢的,它什么也不做。 public static XElement StripNS(XElement xElement) foreach (var node in xElement.DescendantsAndSelf()) node.Name = node.Name.LocalName; return xElement; 【参考方案3】:

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

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

【讨论】:

这没用,伙计! xmlns 未被识别为命名空间。 让我自己测试一下,我会告诉你的 告诉我当你做这样的事情时会发生什么xelement.Attributes("xmlns").Remove(); 什么都没有发生@octavioccl。 xelement 在 Attributes("xmlns").Remove() 之前和之后是一样的 但是你在哪里看到,调试它或在你的文档中,如果是最后一种情况,那么你需要保存更改

以上是关于C# - 如何从 XElement 中删除 xmlns的主要内容,如果未能解决你的问题,请参考以下文章

如何在c#中使用xelement获取xml节点值

C#:如何从 XElement 中获取名称(带前缀)作为字符串?

在 C# 中使用 XElement 获取 XML 的元素节点值

VB.NET:使用 XDocument 在 XML 文件中添加/编辑/删除 XElement

在 C# Compact Framework 中加速 XML 的解析(使用 XmlTextReader 和 XElement)?

c#如何用xelement读取xml属性