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 に答える