两个 XML 文件的智能合并 [英] Smart merging of two XML files

查看:88
本文介绍了两个 XML 文件的智能合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试合并 XML,但我有非常具体的要求.我有以下两个 XML 文件:

I am trying to merge XML but I have very specific requirements. I have following two XML files:

<msg action="getcustomlists" class="lookup" ul="1">
  <host name="hp"/>
</msg>

<msg action="getcustomlists" class="newLookup" lac="statements">
  <environment type="lab">
    <login id="manual" />
  </environment>
</msg>

我想合并这两个文件来制作这样的东西:

I want to merge these two files to make something like this:

<msg action="getcustomlists" class="newLookup" lac="statements" ul="1">
  <host name="hp"/>
  <environment type="lab">
    <login id="manual" />
  </environment>
</msg>

换句话说,我需要合并属性和元素.如果由于重复属性而发生冲突,我们只需要用第二个文件覆盖结果.

In other words, I need to merge attributes and the elements. In case, there is a conflict because of a duplicate attribute, we just need to override the results with the second file.

我已经尝试过 DataSet.Merge(DataSet).但这并没有给我想要的结果.请帮忙.

I have tried DataSet.Merge(DataSet). but that is not giving me desired results. Please help.

谢谢,哈里特

推荐答案

您可以使用 XmlDocument,打开两个源,遍历节点并将其合并到新的 XmlDocument 中.

You can use XmlDocument, open both sources, iterate through nodes and merge it in a new XmlDocument.

此外,借助 XmlDocument,您可以使用 LINQ 来测试冲突,从而简化了这项任务.

Also, with XmlDocument you can use LINQ to test for collisions, what simplifies this task.

    XmlDocument MergeDocs(string SourceA, string SourceB)
    {

        XmlDocument docA = new XmlDocument();
        XmlDocument docB = new XmlDocument();
        XmlDocument merged = new XmlDocument();

        docA.LoadXml(SourceA);
        docB.LoadXml(SourceB);

        var childsFromA = docA.ChildNodes.Cast<XmlNode>();
        var childsFromB = docB.ChildNodes.Cast<XmlNode>();

        var uniquesFromA = childsFromA.Where(ch => childsFromB.Where(chb => chb.Name == ch.Name).Count() == 0);
        var uniquesFromB = childsFromB.Where(ch => childsFromA.Where(chb => chb.Name == ch.Name).Count() == 0);

        foreach (var unique in uniquesFromA)
            merged.AppendChild(DeepCloneToDoc(unique, merged));

        foreach (var unique in uniquesFromA)
            merged.AppendChild(DeepCloneToDoc(unique, merged));

        var Duplicates = from chA in childsFromA
                         from chB in childsFromB
                         where chA.Name == chB.Name
                         select new { A = chA, B = chB };

        foreach (var grp in Duplicates)
            merged.AppendChild(MergeNodes(grp.A, grp.B, merged));

        return merged;

    }

    XmlNode MergeNodes(XmlNode A, XmlNode B, XmlDocument TargetDoc)
    {
        var merged = TargetDoc.CreateNode(A.NodeType, A.Name, A.NamespaceURI);

        foreach (XmlAttribute attrib in A.Attributes)
            merged.Attributes.Append(TargetDoc.CreateAttribute(attrib.Prefix, attrib.LocalName, attrib.NamespaceURI));

        var fromA = A.Attributes.Cast<XmlAttribute>();

        var fromB = B.Attributes.Cast<XmlAttribute>();

        var toAdd = fromB.Where(attr => fromA.Where(ata => ata.Name == attr.Name).Count() == 0);

        foreach (var attrib in toAdd)
            merged.Attributes.Append(TargetDoc.CreateAttribute(attrib.Prefix, attrib.LocalName, attrib.NamespaceURI));

        var childsFromA = A.ChildNodes.Cast<XmlNode>();
        var childsFromB = B.ChildNodes.Cast<XmlNode>();

        var uniquesFromA = childsFromA.Where(ch => childsFromB.Where(chb => chb.Name == ch.Name).Count() == 0);
        var uniquesFromB = childsFromB.Where(ch => childsFromA.Where(chb => chb.Name == ch.Name).Count() == 0);

        foreach (var unique in uniquesFromA)
            merged.AppendChild(DeepCloneToDoc(unique, TargetDoc));

        foreach (var unique in uniquesFromA)
            merged.AppendChild(DeepCloneToDoc(unique, TargetDoc));

        var Duplicates = from chA in childsFromA
                         from chB in childsFromB
                         where chA.Name == chB.Name
                         select new { A = chA, B = chB };

        foreach(var grp in Duplicates)
            merged.AppendChild(MergeNodes(grp.A, grp.B, TargetDoc));

        return merged;
    }

    XmlNode DeepCloneToDoc(XmlNode NodeToClone, XmlDocument TargetDoc)
    {

        var newNode = TargetDoc.CreateNode(NodeToClone.NodeType, NodeToClone.Name, NodeToClone.NamespaceURI);

        foreach (XmlAttribute attrib in NodeToClone.Attributes)
            newNode.Attributes.Append(TargetDoc.CreateAttribute(attrib.Prefix, attrib.LocalName, attrib.NamespaceURI));

        foreach (XmlNode child in NodeToClone.ChildNodes)
            newNode.AppendChild(DeepCloneToDoc(NodeToClone, TargetDoc));

        return newNode;

    }

请注意,我还没有测试过,只是凭记忆完成的,但您知道如何去做.

Note I haven't tested it, done just from memory but you get the idea about how to go.

这篇关于两个 XML 文件的智能合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆