2016-12-15 59 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。

相关问题