我是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);
}
}
}
}
有人可以帮我解释代码以完成合并任务吗? 提前谢谢。
答案 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}