2016-12-15 9 views
1

私は私のxmlファイルにC#でXMLの値を保持して、すべての属性名を変更する方法は?

<CPU> 
<NEW type="DOS" model="SV112">dos-8875</NEW> 
<NEW type="DIN" model="SV544">din-9984</NEW> 
<NEW type="FTP" model="SV774">ftp-9952</NEW> 
<NEW type="DOS" model="SV112">dos-8854</NEW> 
</CPU> 

これを持っていると私はここでは、この

<CPU> 
<NEW name="DOS" model-no="SV112">dos-8875</NEW> 
<NEW name="DIN" model-no="SV544">din-9984</NEW> 
<NEW name="FTP" model-no="SV774">ftp-9952</NEW> 
<NEW name="DOS" model-no="SV112">dos-8854</NEW> 
</CPU> 

ようにそれを作りたいが、私はこれまでやっていることですが、残念ながらこれは単に最初の属性を変更します。

string path = @"d:\test.xml"; 
XDocument doc = XDocument.Load(path); 
var element = doc.Root.Element("NEW"); 
var list = element.Attributes().ToList(); 
var oldAttr = list.Where(p => p.Name == "type").SingleOrDefault(); 
if (oldAttr != null) 
{ 
    XAttribute newAttr = new XAttribute("name", oldAttr.Value); 
    list.Add(newAttr); 
    list.Remove(oldAttr); 
    element.ReplaceAttributes(list); 
} 
Console.WriteLine(doc.ToString()); 

すべての属性名を変更したいのですが、どのようにこれをXDocumentで行うことができますか?

擬似コード:

element[0].attribute[0].name = "type"; 
element[1].attribute[0].name = "type"; 
element[2].attribute[1].name = "model-no"; 
+0

これをデシリアライズする必要があると思います。この記事では、名前の制御などについて説明しています。https://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.110).aspx – Michael

+0

値のために送信したリンクですが、属性名が必要です – w3000cpu

答えて

3

XAttribute.Nameは変更できませんとあなたはかなり、あなたの擬似コードを示唆して何ができない(あなたが簡単に要素の名前を変更することができますのでさておき、XElement.Nameが可変であるため)。

唯一のオプションは、既存の属性を削除し、同じ名前の別の属性を追加することです。これらを出力XMLごとに同じ順序で保持したい場合は、すべての属性を新しいセットに置き換える必要があります。 MapAttributeはこのようなものである

foreach (var element in doc.Descendants("NEW")) 
{ 
    element.ReplaceAttributes(
     element.Attributes().Select(MapAttribute)); 
} 

private static XAttribute MapAttribute(XAttribute attribute) 
{ 
    switch (attribute.Name.LocalName) 
    { 
     case "type": 
      return new XAttribute("name", attribute.Value); 
     case "model": 
      return new XAttribute("model-no", attribute.Value); 
     default: 
      return attribute; 
    } 
} 

は、作業のデモ用this fiddleを参照してください。

1

は、私はあなたがこの意味を考える:ジョブはXSLTである等の

foreach (var element in xml.Root.Elements()) //or use xml.Descendants("NEW") 
{ 
    var att = element.Attributes().SingleOrDefault(a => a.Name == "model"); 
    element.SetAttributeValue(XName.Get("model-no"), att?.Value ?? ""); 
    att.Remove(); 
} 
0

この

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      XDocument doc = XDocument.Load(FILENAME); 

      foreach (XElement descendant in doc.Descendants()) 
      { 
       for (int i = descendant.Attributes().Count() - 1; i > 0; i--) 
       { 
        XAttribute attr = descendant.Attributes().Skip(i).FirstOrDefault(); 
        switch (attr.Name.LocalName) 
        { 
         case "type": 
          descendant.Add(new XAttribute("name", attr.Value)); 
          attr.Remove(); 
          break; 

         case "model": 
          descendant.Add(new XAttribute("model-no", attr.Value)); 
          attr.Remove(); 
          break; 

        } 
       } 
      } 
     } 
    } 
} 
0

最良のツールをお試しください。これがXSLT hereでどのように行われているかを見ることができます。あなたのケースでは、これは次のようになります。/ NET C#でXSLTを適用する方法について

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="@type"> 
    <xsl:attribute name="name"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 

<xsl:template match="@model"> 
    <xsl:attribute name="model-no"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 

チェックthis linkを。

string transformation = "...your XSLT..."; 

XDocument destinationDoc = new XDocument(); 
XmlWriter destinationWriter = destinationDoc.CreateWriter() 
using (destinationWriter) { 
    XslCompiledTransform xslt = new XslCompiledTransform(); 
    XmlReader transformationReader = XmlReader.Create(new StringReader(transformation)); 
    using (transformationReader) { 
     xslt.Load(transformationReader); 
    } 
    XmlReader docReader = doc.CreateReader(); 
    using (docReader) { 
     xslt.Transform(docReader, destinationWriter); 
    } 
} 

XSLTが具体的にあなたのようなXML変換のために設計されており、あなたに最大限の柔軟性を提供します:あなたが必要なもの

は、変換を行いますXslCompiledTransformです。

私が一般的に行うことは、プロジェクトにXSLTファイルを追加し、アセンブリリソースファイルを作成してXSLTをリンクすることです。

関連する問題