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 (非修飾) は属性自体ではなく、要素の名前の一部と見なされます。

<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 文字の長さでなければなりません :)

于 2012-08-10T10:38:33.247 に答える
2

xmlns単なる属性ではありません。タイプを定義します。値を持つ属性を持つWindow単なる要素ではありません。むしろ、「http://schemas.microsoft.com/winfx/2006/xaml/presentation」名前空間で呼び出される要素です。単純に名前空間を変更することもできますが、それが合法であるとは思いません (不変であると予想します)。WindowsxmlnsWindowWindow XName

別名:これには別の方法でアプローチする必要があります。

于 2012-08-10T10:37:39.213 に答える