使用 LINQ to XML 删除属性不会持续存在
Posted
技术标签:
【中文标题】使用 LINQ to XML 删除属性不会持续存在【英文标题】:Removing attribute using LINQ to XML does not persists 【发布时间】:2012-08-07 15:28:26 【问题描述】:我有以下 xml,我正在尝试使用 LINQ to XML 从中删除所有“xmlns”属性:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<LinearLayout xmlns="clr-namespace:androidAssembly;assembly=AndroidAssembly"/>
<TextView xmlns="clr-namespace:AndroidAssembly;assembly=AndroidAssembly">
</StackPanel>
</Window>
使用以下代码。它为文档中的每个“xmlns”属性命中“attributesToRemove.Remove()”。但是当我保存文档时,我仍然拥有原始 XML。任何想法,可能是什么问题?
var sr = new StringReader(richTextBoxOriginalXml.Text);
XDocument xdoc = XDocument.Load(sr);
foreach(var node in xdoc.Descendants().ToList())
var xmlns = node.Attributes().FirstOrDefault(a => a.Name == "xmlns");
if (xmlns !=null)
var attributesToRemove = node.Attributes("xmlns").ToList();
attributesToRemove.Remove();
var writer = new StringWriter();
var xmlWriter = new XmlTextWriter(writer);
xmlWriter.Formatting = Formatting.Indented;
xdoc.WriteTo(xmlWriter);
richTextBoxTransformed.Text = writer.GetStringBuilder().ToString();
【问题讨论】:
为什么不使用 XDocument 类中的 Remove 方法? XDocument .Remove() 删除一个节点。我需要删除一个属性。 【参考方案1】:就像 Marc Gravell 在我发布之前指出的那样,xmlns
属性(不合格)本身并不是一个属性,它被认为是元素名称的一部分。
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<LinearLayout xmlns="clr-namespace:AndroidAssembly;assembly=AndroidAssembly" />
<TextView xmlns="clr-namespace:AndroidAssembly;assembly=AndroidAssembly" />
</StackPanel>
StackPanel
标签在这里没有属性。然而,它的名字是http://schemas.microsoft.com/winfx/2006/xaml/presentationStackPanel
。
Name.Namespace
是http://schemas.microsoft.com/winfx/2006/xaml/presentation
(XNamespace
类型)和Name.LocalName == "StackPanel"
。
因此,您需要有效地重命名元素。它应该可以工作。
过度简化(但可编译)的程序:
using System;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApplication
class Program
static void Main(string[] args)
var raw = @"<Window xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
<StackPanel>
<LinearLayout xmlns=""clr-namespace:AndroidAssembly;assembly=AndroidAssembly""/>
<TextView xmlns=""clr-namespace:AndroidAssembly;assembly=AndroidAssembly""/>
</StackPanel>
</Window>";
var xml = XElement.Parse(raw);
var descendants = xml.Descendants().ToArray();
var stackPanel = descendants.First();
Console.WriteLine(stackPanel.ToString());
Console.WriteLine("==================================");
stackPanel.Name = stackPanel.Name.LocalName; // stripping the namespace off
Console.WriteLine(stackPanel.ToString());
Console.ReadLine();
输出:
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<LinearLayout xmlns="clr-namespace:AndroidAssembly;assembly=AndroidAssembly" />
<TextView xmlns="clr-namespace:AndroidAssembly;assembly=AndroidAssembly" />
</StackPanel>
==================================
<StackPanel>
<LinearLayout xmlns="clr-namespace:AndroidAssembly;assembly=AndroidAssembly" />
<TextView xmlns="clr-namespace:AndroidAssembly;assembly=AndroidAssembly" />
</StackPanel>
StackPanel
元素的区别很容易注意到...
顺便说一句,您发布的 XML 中有一个错字(TextView
标签未关闭),但我无法编辑它 - 编辑必须至少有 6 个字符长 :)(为什么是 6 个?)
【讨论】:
是的,我明白了。谢谢你。我将使用这种方法。 @Peter17 很高兴我能提供帮助 - 如果它解决了您的问题,请将我的回答标记为已接受【参考方案2】:xmlns
不仅仅是一个属性;它定义类型。 Window
不仅仅是一个名为 Windows
的元素,它具有属性 xmlns
和一个值;相反:Window
是一个名为 Window
的元素在“http://schemas.microsoft.com/winfx/2006/xaml/presentation”命名空间中。您可以尝试简单地更改命名空间,但我不认为这是合法的(我希望 XName
是不可变的)。
aka:您将需要以不同的方式处理此问题。
【讨论】:
谢谢。我会尝试别的。以上是关于使用 LINQ to XML 删除属性不会持续存在的主要内容,如果未能解决你的问题,请参考以下文章