2012-09-10 2 views
1

2 개의 xml 파일을 함께 병합해야하지만 두 파일에 나타나는 요소를 모두 고려해야합니다.LINQ를 사용하여 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

당신이 봤어 여기 생각 : ** HTTP : //stackoverflow.com/questions/4937875/merging -two-xml-files-linq ** –

답변

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

이 완벽하게 완성되지 않은,하지만 난 구조가

+0

감사합니다. @ tschmit007 - 정말로 정말로 닫습니다 :) !! 몇 가지 질문 : - 1. 출력은 요소의 병합을 수행하지만 Xml1과 Xml2에 Label2가 있고 글꼴이 Arial (Tahoma의)으로 업데이트되어야한다는 사실을 인식하지 못합니다. 나는 네가 여기있는 조건이 '거기 없다고 생각해.'라고 생각합니다. 거의 나를 위해 일한다! 2. Xml1 : BaseStyle에서 BackgroundPath 속성은 "BackgroundAAA.png"인 반면 Xml2에서는 BackgroundBBB.png입니다. '병합하여 최종 결과가 Xml3에 따라 가능합니까? 답장을 보내 주셔서 감사합니다. 정말로 감사드립니다. – Slippy

+0

여기에 실제 코드에서 처리 할 수 ​​있다고 생각합니다. – tschmit007