1

我需要将 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 做到这一点?

提前致谢!

4

1 回答 1

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());
    }
}

这还没有完全确定,但我认为结构就在这里

于 2012-09-10T16:07:28.613 回答