[英]How to the replace node names with new name and keep the attributes using C# and Linq to 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.