2012-08-10 22 views
1

我有以下XML,从中我想删除所有“的xmlns”属性使用LINQ to XML:删除属性不挖墙角

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

为什么不使用XDocument类中的Remove方法? – h1ghfive 2012-08-10 10:34:03

+0

XDocument .Remove()删除一个节点。我需要删除一个属性。 – Peter17 2012-08-10 10:35:50

回答

3

像我之前发布的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/presentation}StackPanel

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?)

+0

是的,我明白了。谢谢。我会用这种方法。 – Peter17 2012-08-10 10:45:07

+0

@ Peter17很高兴我可以帮助 - 请将我的答案标记为已接受的答案,如果它解决了您的问题 – 2012-08-10 11:04:43

2

xmlns不仅仅是一个属性;它定义了的类型。 Window不仅仅是一个名为Windows的元素,它具有值为xmlns的属性;而是:Window是“http://schemas.microsoft.com/winfx/2006/xaml/presentation”命名空间中名为Window的元素。你可以尝试简单地改变命名空间,但我不希望这是合法的(我期望XName是不可变的)。

又名:你将需要采取不同的方式。

+0

谢谢。我会尝试别的。 – Peter17 2012-08-10 10:40:25