[英]Merge attributes of two xml with same structure in c#
我有兩種具有以下結構的XML:
XML 1:
<function>
<subfunction id="s1" value="s1">
<display id="1" value="a"></display>
<display id="2" value="b"></display>
<display id="3" value="c"></display>
<display id="4" value="d"></display>
</subfunction>
</function>
XML 2:
<function>
<subfunction id="s1" some-value="other">
<display id="1" another-data="something"></display>
<display id="2" another-data="something"></display>
<display id="3" another-data="something"></display>
<display id="4" another-data="something"></display>
</subfunction>
</function>
我想合並這兩個XML,所以最終輸出看起來像這樣:
<function>
<subfunction id="s1" value="s1" some-value="other">
<display id="1" value="a" another-data="something"></display>
<display id="2" value="b" another-data="something"></display>
<display id="3" value="c" another-data="something"></display>
<display id="4" value="d" another-data="something"></display>
</subfunction>
</function>
當前,我在C#中使用forEach循環合並這兩個XML,效率非常低。 還有其他方法可以一次性執行此操作嗎?
我正在使用以下代碼進行合並
public XmlDocument MergeXMLAttributes(XmlDocument doc, XmlDocument trimmedXmlDoc)
{
var nodes = trimmedXmlDoc.DocumentElement.SelectNodes("//*");
foreach (XmlElement displayNode in nodes)
{
var nodeId = displayNode.GetAttribute("id");
var nodeXPath = String.Format("//*[@id='{0}']", nodeId);
XmlElement fullNode = doc.SelectSingleNode(nodeXPath) as XmlElement;
foreach (XmlAttribute attribute in displayNode.Attributes)
{
fullNode.SetAttribute(attribute.Name, attribute.Value);
}
}
return doc;
}
static void Main(string[] args)
{
var xml1 = XElement.Parse(@"<function>
<subfunction id=""s1"" value=""s1"">
<display id=""1"" value=""a""></display>
<display id=""2"" value=""b""></display>
<display id=""3"" value=""c""></display>
<display id=""4"" value=""d""></display>
</subfunction>
</function>");
var xml2 = XElement.Parse(@"<function>
<subfunction id=""s1"" some-value=""other"">
<display id=""1"" another-data=""something""></display>
<display id=""2"" another-data=""something""></display>
<display id=""3"" another-data=""something""></display>
<display id=""4"" another-data=""something""></display>
</subfunction>
</function>");
var xml3 = Merge(xml1, xml2);
Console.WriteLine(xml3.ToString());
Console.ReadLine();
}
private static XElement Merge(XElement thisElement, XElement otherElement)
{
if(thisElement.Name == otherElement.Name)
{
var merged = new XElement(thisElement.Name);
merged.ReplaceAttributes(Attributes(thisElement, otherElement).ToArray());
var thisChildren = thisElement.Elements().Where(e => e.Attribute("id") != null);
if(thisChildren.Any())
{
var children = thisChildren.Select(thisChild => {
var otherChild = otherElement
.Elements()
.Where(e => e.Attribute("id") != null && e.Attribute("id").Value == thisChild.Attribute("id").Value)
.FirstOrDefault();
if(otherChild != null)
{
return Merge(thisChild, otherChild);
}
return null;
}).Where(child => child != null);
merged.Add(children.ToArray());
}
return merged;
}
return null;
}
private static IEnumerable<XAttribute> Attributes(XElement thisElement, XElement otherElement)
{
return thisElement
.Attributes()
.Concat(otherElement.Attributes())
.GroupBy(a => a.Name)
.Select(g => g.FirstOrDefault())
.Where(a => a != null);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.