2016-12-15 54 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保持這些順序,那麼您需要用新的集合替換所有的屬性。

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

哪裏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中看到如何完成此操作。在你的情況,這將是這樣的:

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

如何在C#/。NET應用XSLT檢查this link

你需要的是一個XslCompiledTransform,將做轉型:

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轉換設計,給你最大的靈活性。

我通常所做的是將XSLT文件添加到項目中,創建程序集資源文件並鏈接XSLT。

相關問題