簡體   English   中英

在C#中合並具有相同結構的兩個xml的屬性

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM