我需要将2个xml文件“合并”在一起,但要考虑两者中出现的元素和每个中不同的合并属性。这是我的意思的一个例子:
输入:Xml1
<?xml version="1.0"?>
<Style Width="1024" Height="768">
<BaseStyle Width="1024" Height="768" BackgroundPath="./Images/BackgroundAAA.png"/>
<Styles>
<LabelStyle ID="Label1" Font="Tahoma" Bold="false" /> <!-- exists in both -->
<LabelStyle ID="Label2" Font="Tahoma" Bold="false" /> <!-- exists in both -->
<LabelStyle ID="Label3" Font="Tahoma" Bold="false" /> <!-- unique -->
</Styles>
</Style>
输入:Xml2
<?xml version="1.0"?>
<Style Width="1024" Height="768">
<BaseStyle Width="1024" Height="768" BackgroundPath="./Images/BackgroundBBB.png"/>
<Styles>
<LabelStyle ID="Label1" Font="Arial" Bold="true" /> <!-- exists in both -->
<LabelStyle ID="Label2" Font="Arial" /> <!-- exists in both -->
<LabelStyle ID="Label4" Font="Arial" Bold="false" /> <!-- unique -->
</Styles>
</Style>
我需要输出以下内容: -
结果:Xml3
<?xml version="1.0"?>
<Style Width="1024" Height="768">
<BaseStyle Width="1024" Height="768" BackgroundPath="./Images/BackgroundBBB.png"/> <!-- has overwritten Xml1 -->
<Styles>
<LabelStyle ID="Label1" Font="Arial" Bold="true" /> <!-- has merged Xml1 & Xml2 with Xml2 taking precedence -->
<LabelStyle ID="Label2" Font="Arial" Bold="false" /> <!-- has merged Xml1 & Xml2 with Xml2 taking precedence (note Bold attribute is present) -->
<LabelStyle ID="Label3" Font="Tahoma" Bold="false" /> <!-- unique -->
<LabelStyle ID="Label4" Font="Arial" Bold="false" /> <!-- unique -->
</Styles>
</Style>
你会从上面注意到任何唯一的东西都会合并,任何常见的东西(使用ID作为键)都会用Xml2值更新。
我一直在阅读有关如何使用LINQ合并2个xml文件的许多重要问题,但没有一个真正满足我的要求。他们似乎都在谈论采取A和B并以A + B结束。
使用LINQ有一种简单的方法吗?
提前致谢!
答案 0 :(得分:2)
例如:
class Program {
static void Main(string[] args) {
StringReader sr = new StringReader("<?xml version=\"1.0\"?><Style Width=\"1024\" Height=\"768\"><BaseStyle Width=\"1024\" Height=\"768\" BackgroundPath=\"./Images/BackgroundBBB.png\"/><Styles><LabelStyle ID=\"Label1\" Font=\"Arial\" Bold=\"true\" /> <!-- exists in both --><LabelStyle ID=\"Label2\" Font=\"Arial\" /> <!-- exists in both --><LabelStyle ID=\"Label3\" Font=\"Arial\" Bold=\"false\" /> <!-- unique --></Styles></Style>");
XDocument xdoc1 = XDocument.Load(sr);
sr.Close();
sr = new StringReader("<?xml version=\"1.0\"?><Style Width=\"1024\" Height=\"768\"><BaseStyle Width=\"1024\" Height=\"768\" BackgroundPath=\"./Images/BackgroundBBB.png\"/><Styles><LabelStyle ID=\"Label1\" Font=\"Arial\" Bold=\"true\" /> <!-- exists in both --><LabelStyle ID=\"Label2\" Font=\"Arial\" /> <!-- exists in both --><LabelStyle ID=\"Label4\" Font=\"Arial\" Bold=\"false\" /> <!-- unique --></Styles></Style>");
XDocument xdoc2 = XDocument.Load(sr);
sr.Close();
sr = new StringReader("<?xml version=\"1.0\"?><Style Width=\"1024\" Height=\"768\"><BaseStyle Width=\"1024\" Height=\"768\" BackgroundPath=\"./Images/BackgroundBBB.png\"/><Styles></Styles></Style>");
XDocument xDocDest = XDocument.Load(sr);
sr.Close();
XElement xeDest = xDocDest.Root.Descendants("Styles").Single();
XElement[] x2s = (from x in xdoc2.Root.Descendants("LabelStyle") orderby x.Attribute("ID").Value select x).ToArray() ;
Int32 iCurrentX2 = 0;
XElement xeCurrentX2 = (x2s.Count() > 1) ? x2s[0] : null;
foreach (XElement x1 in from x in xdoc1.Root.Descendants("LabelStyle") orderby x.Attribute("ID").Value select x) {
if (xeCurrentX2 == null || String.Compare(x1.Attribute("ID").Value, xeCurrentX2.Attribute("ID").Value) < 0) {
xeDest.Add(x1);
} else {
while (iCurrentX2 < x2s.Count() && String.Compare(x1.Attribute("ID").Value, xeCurrentX2.Attribute("ID").Value) >= 0) {
xeDest.Add(xeCurrentX2);
xeCurrentX2 = (++iCurrentX2 < x2s.Count()) ? x2s[iCurrentX2] : null;
}
}
}
while (iCurrentX2 < x2s.Count()) {
xeDest.Add(x2s[iCurrentX2++]);
}
Console.WriteLine(xDocDest.ToString());
}
}
这不是完美的,但我认为结构在这里