繁体   English   中英

如何使用C#中的XML值保留所有属性名称?

[英]How to change all Attributes Names with keep the values in XML in 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";

您不能完全按照伪代码的建议进行操作,因为XAttribute.Name不可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;
    }
}

请参阅此小提琴以获得有效的演示。

我想你的意思是:

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();
}

尝试这个

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;

                    }
                }
            }
        }
    }
}

诸如此类的最佳工具是XSLT。 您可以在此处查看如何在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>

检查此链接 ,了解如何在C#/。NET中应用XSLT。

您需要一个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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM