1

我有以下 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();
4

2 回答 2

3

就像 Marc Gravell 在我发布之前指出的那样,xmlnsattribute (unqualified) 本身并不是一个属性,它被认为是元素名称的一部分。

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

StackPaneltag 这里没有属性。然而,它的名字是{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 个?)

于 2012-08-10T10:38:33.247 回答
2

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

又名:您将需要以不同的方式处理此问题。

于 2012-08-10T10:37:39.213 回答