如何在C#中合并2个xmls?

时间:2015-08-30 10:25:07

标签: xml merge

我是C#的新手,我正在尝试使用相同的方法合并两个XML文件。我试过了diff和patch程序集。但似乎没什么可锻炼的。我需要合并的2个Xml文件如下:

文件A是原始文件。具体如下:

<?xml version="1.0" encoding="utf-8"?>
<Dashboards xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Dashboard name="A">
    <Controls>
      <Control>
        <DashboardControls>
          <DashboardControl name="b" structure="abc" Layout="true">
          <DashboardControl name="c" structure="abcd" Layout="true">
            <SubstituteBoards>
                <DashboardControl name="c" structure="abcd" Layout="true" />
                <DashboardControl name="d" structure="abcde" Layout="true"/>
              </SubstituteBoards>
            </DashboardControl >
            </DashboardControl >
        </DashboardControls>
      </Control>
    </Controls>
  </Dashboard >
  <Dashboard name="B">
    <Controls>
      <Control>
        <DashboardControls>
          <DashboardControl name="b" structure="abc" Layout="true">
            <SubstituteBoards>
              <DashboardControl name="d"  structure="abcde" Layout="true"/>
              <DashboardControls name="c" structure="abcd" Layout="true" />
            </SubstituteBoards>
          </DashboardControl >
        </DashboardControls>
      </Control>
    </Controls>
  </Dashboard >
</Dashboards >

文件B是文件,其中包含新节点和文件A中已存在的节点的混合。

文件B如下:

<?xml version="1.0" encoding="utf-8"?>
<Dashboards xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Dashboard name="A">
    <Controls>
      <Control>
        <DashboardControls>
          <DashboardControl name="b" structure="abc" Layout="true">
          <DashboardControl name="b" structure="abc" Layout="true">
            <SubstituteBoards>
                <DashboardControl name="c" structure="abcd" Layout="true" />
                <DashboardControl name="d" structure="abcde" Layout="true"/>
                <DashboardControl name="b" structure="abc" Layout="true"/>
              </SubstituteBoards>
            </DashboardControl>
            </DashboardControl>
        </DashboardControls>
      </Control>
    </Controls>
  </Dashboard >
  <Dashboard name="B">
    <Controls>
      <Control>
        <DashboardControls>
          <DashboardControl name="b" structure="abc" Layout="true">
            <SubstituteBoards>
              <DashboardControl name="d"  structure="abcde" Layout="true"/>
              <DashboardControls name="c" structure="abcd" Layout="true" />
            </SubstituteBoards>
          </DashboardControl>
        </DashboardControls>
      </Control>
    </Controls>
  </Dashboard>
</Dashboards>

因此合并的文件应该是

 <?xml version="1.0" encoding="utf-8"?>
<Dashboards xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Dashboard name="A">
    <Controls>
      <Control>
        <DashboardControls>
          <DashboardControl name="b" structure="abc" Layout="true">
          <DashboardControl name="b" structure="abc" Layout="true">
          <DashboardControl name="c" structure="abcd" Layout="true">
            <SubstituteBoards>
                <DashboardControl name="c" structure="abcd" Layout="true" />
                <DashboardControl name="d" structure="abcde" Layout="true"/>
                <DashboardControl name="b" structure="abc" Layout="true"/>
              </SubstituteBoards>
            </DashboardControl>
            </DashboardControl>
            </DashboardControl>
        </DashboardControls>
      </Control>
    </Controls>
  </Dashboard >
  <Dashboard name="B">
    <Controls>
      <Control>
        <DashboardControls>
          <DashboardControl name="b" structure="abc" Layout="true">
            <SubstituteBoards>
              <DashboardControl name="d"  structure="abcde" Layout="true"/>
              <DashboardControls name="c" structure="abcd" Layout="true" />
            </SubstituteBoards>
          </DashboardControl >
        </DashboardControls>
      </Control>
    </Controls>
  </Dashboard >
</Dashboards >

我尝试过的xml差异和补丁代码如下:

private void button1_Click(object sender, EventArgs e)
    {

        XmlWriter diffGramWriter = XmlWriter.Create(@"path of the diffgram  file to be created");
        GenerateDiffGram(@"Path of file A.xml", @"path of diffgram file.xml", diffGramWriter);
        PatchUp(@"Path of file A.xml", @"path of diffgram file.xml", @"Path of merged file created.xml");



    }
    public void GenerateDiffGram(string originalFile, string finalFile, XmlWriter diffGramWriter)
    {

        XmlDiff xmldiff = new XmlDiff();
        bool bIdentical = xmldiff.Compare(originalFile, @"Path of file B.xml", true, diffGramWriter);
        diffGramWriter.Close();
    }

    public void PatchUp(string originalFile, String diffGramFile, string OutputFile)
    {
        StringBuilder sb = new StringBuilder();
        XmlDocument sourceDoc = new XmlDocument(new NameTable());
        sourceDoc.Load(originalFile);
        XmlTextReader diffgramReader = new XmlTextReader(diffGramFile);
        XmlPatch xmlpatch = new XmlPatch();
        xmlpatch.Patch(sourceDoc, diffgramReader);
        XmlWriterSettings settings = new XmlWriterSettings { Indent = true };
        using (XmlWriter output = XmlWriter.Create(OutputFile, settings))
        {
            sourceDoc.Save(output);
        }

              }

}

}

有人可以帮我解释代码以完成合并任务吗? 提前谢谢。

2 个答案:

答案 0 :(得分:0)

以下代码的工作原理除外,原始数据中包含重复的内容。那是对的吗?如果您有两个列表1)g 2)g,g:您希望合并列表包含g,g?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string a = 
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                    "<Dashboards xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
                      "<Dashboard name=\"A\">" +
                        "<Controls>" +
                          "<Control>" +
                            "<DashboardControls>" +
                              "<DashboardControl name=\"b\" structure=\"abc\" Layout=\"true\">" +
                              "<DashboardControl name=\"c\" structure=\"abcd\" Layout=\"true\">" +
                                "<SubstituteBoards>" +
                                    "<DashboardControl name=\"c\" structure=\"abcd\" Layout=\"true\" />" +
                                    "<DashboardControl name=\"d\" structure=\"abcde\" Layout=\"true\"/>" +
                                  "</SubstituteBoards>" +
                                "</DashboardControl >" +
                                "</DashboardControl >" +
                            "</DashboardControls>" +
                          "</Control>" +
                        "</Controls>" +
                      "</Dashboard >" +
                      "<Dashboard name=\"B\">" +
                        "<Controls>" +
                          "<Control>" +
                            "<DashboardControls>" +
                              "<DashboardControl name=\"b\" structure=\"abc\" Layout=\"true\">" +
                                "<SubstituteBoards>" +
                                  "<DashboardControl name=\"d\"  structure=\"abcde\" Layout=\"true\"/>" +
                                  "<DashboardControls name=\"c\" structure=\"abcd\" Layout=\"true\" />" +
                                "</SubstituteBoards>" +
                              "</DashboardControl >" +
                            "</DashboardControls>" +
                          "</Control>" +
                        "</Controls>" +
                      "</Dashboard >" +
                    "</Dashboards >";

            string b =
              "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                  "<Dashboards xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
                    "<Dashboard name=\"A\">" +
                      "<Controls>" +
                        "<Control>" +
                          "<DashboardControls>" +
                            "<DashboardControl name=\"b\" structure=\"abc\" Layout=\"true\">" +
                            "<DashboardControl name=\"b\" structure=\"abc\" Layout=\"true\">" +
                              "<SubstituteBoards>" +
                                  "<DashboardControl name=\"c\" structure=\"abcd\" Layout=\"true\" />" +
                                  "<DashboardControl name=\"d\" structure=\"abcde\" Layout=\"true\"/>" +
                                  "<DashboardControl name=\"b\" structure=\"abc\" Layout=\"true\"/>" +
                                "</SubstituteBoards>" +
                              "</DashboardControl>" +
                              "</DashboardControl>" +
                          "</DashboardControls>" +
                        "</Control>" +
                      "</Controls>" +
                    "</Dashboard >" +
                    "<Dashboard name=\"B\">" +
                      "<Controls>" +
                        "<Control>" +
                          "<DashboardControls>" +
                            "<DashboardControl name=\"b\" structure=\"abc\" Layout=\"true\">" +
                              "<SubstituteBoards>" +
                                "<DashboardControl name=\"d\"  structure=\"abcde\" Layout=\"true\"/>" +
                                "<DashboardControls name=\"c\" structure=\"abcd\" Layout=\"true\" />" +
                              "</SubstituteBoards>" +
                            "</DashboardControl>" +
                          "</DashboardControls>" +
                        "</Control>" +
                      "</Controls>" +
                    "</Dashboard>" +
                  "</Dashboards>";


            XDocument docA = XDocument.Parse(a);
            XDocument docB = XDocument.Parse(b);

           foreach(XElement aDashboard in docA.Descendants("Dashboard"))
           {
               List<XElement> aDashboardControls = null;
               List<XElement> bDashboardControls = null;
               List<XElement> addControls = null;

               XElement bDashboard = docB.Descendants("Dashboard").Where(x => x.Attribute("name").Value == aDashboard.Attribute("name").Value).FirstOrDefault();
               aDashboardControls = aDashboard.Descendants("DashboardControls").ToList();
               bDashboardControls = bDashboard.Descendants("DashboardControls").ToList();

               addControls = bDashboardControls.Elements("DashboardControl").Where(x => aDashboardControls.Elements("DashboardControl").Where(y => CompareControl(x, y)).Count() == 0).ToList();
               aDashboardControls.AddRange(addControls);

               XElement aSubstituteBoards = aDashboard.Descendants("SubstituteBoards").FirstOrDefault();
               XElement bSubstituteBoards = bDashboard.Descendants("SubstituteBoards").FirstOrDefault();


               addControls = bSubstituteBoards.Elements("DashboardControl").Where(x => aSubstituteBoards.Elements("DashboardControl").Where(y => CompareControl(x, y)).Count() == 0).ToList();
               aSubstituteBoards.Add(addControls);


           }
        }
        static Boolean CompareControl(XElement a, XElement b)
        {
            Boolean results = true;
            if (a.Attribute("name").Value != b.Attribute("name").Value)
            {
                results = false;
            }
            else
            {
                if (a.Attribute("structure").Value != b.Attribute("structure").Value)
                {
                    results = false;
                }
                else
                {
                    if (a.Attribute("Layout").Value != b.Attribute("Layout").Value)
                    {
                        results = false;
                    }
                }
            }

            return results;
        }
    }
}
​

答案 1 :(得分:0)

以下是您的要求示意图。我没有足够的信息来编写合并代码。看文件A&#34; A&#34;案例和文件B&#34; A&#34;案例的例子很模糊。在一个案例中,SubstituteBoards是&#34; b&#34;的孩子。另一种情况SubstituteBoards是&#34; c&#34;。

的孩子
File A
A = b -> c -> SubstituteBoards {c,d}
B = b -> SubstituteBoards {d,c}
File B
A = b - > b -> SubstituteBoards {c,d,b}
B = b -> SubstituteBoards { d, c}

Results
A = b -> b -> c -> SubstituteBoards {c,d,b}
B = b -> SubstituteBoards {d,c}​