2015-07-28 42 views
2

我試圖合併XElements的兩個列表,像這樣:如何合併兩個使用Linq的XElements列表?

列表1:

<Element name="foo"> 
    <ChildElement name="childFoo"> 
     <SubChildElement name="subChildFoo" /> 
    </ChildElement> 
</Element> 
<Element name="bar"> 
    <ChildElement name="childBar"> 
     <SubChildElement name="subChildBar" /> 
    </ChildElement> 
</Element> 
<Element name="zoo" /> 

列表2:

<Element name="foo" attr="fooAtr" /> 
<Element name="bar" attr="barAtr" /> 
<Element name="zoo" attr="barAtr" /> 

,結果應該是這樣的:

<Element name="foo" attr="fooAtr"> 
    <ChildElement name="childFoo"> 
     <SubChildElement name="subChildFoo" /> 
    </ChildElement> 
</Element> 
<Element name="bar" attr="barAtr"> 
    <ChildElement name="childBar"> 
     <SubChildElement name="subChildBar" /> 
    </ChildElement> 
</Element> 
<Element name="zoo" attr="barAtr" /> 

我嘗試使用.Concat()方法,但它只是將它們加在一起:

var merged_list = list1.Concat(list2); 

我想將具有相同名稱屬性的元素合併爲一個。我如何使用linq來做到這一點?

回答

1

你能list2到字典中並應用屬性list1

var doc1 = XDocument.Parse(@" 
    <root> 
     <Element name=""foo""> 
      <ChildElement name=""childFoo""> 
       <SubChildElement name=""subChildFoo"" /> 
      </ChildElement> 
     </Element> 
     <Element name=""bar""> 
      <ChildElement name=""childBar""> 
       <SubChildElement name=""subChildBar"" /> 
      </ChildElement> 
     </Element> 
     <Element name=""zoo"" /> 
    </root>"); 

var doc2 = XDocument.Parse(@" 
    <root> 
     <Element name=""foo"" attr=""fooAtr"" /> 
     <Element name=""bar"" attr=""barAtr"" /> 
     <Element name=""zoo"" attr=""barAtr"" /> 
    </root>"); 

var attributes = doc2.Descendants("Element") 
    .ToDictionary(e => e.Attribute("name").Value, e => e.Attribute("attr").Value); 
doc1.Descendants("Element") 
    .ToList() 
    .ForEach(e => e.Add(new XAttribute("attr", attributes[e.Attribute("name").Value]))); 
Console.WriteLine(doc1); 

輸出:

<root> 
    <Element name="foo" attr="fooAtr"> 
    <ChildElement name="childFoo"> 
     <SubChildElement name="subChildFoo" /> 
    </ChildElement> 
    </Element> 
    <Element name="bar" attr="barAtr"> 
    <ChildElement name="childBar"> 
     <SubChildElement name="subChildBar" /> 
    </ChildElement> 
    </Element> 
    <Element name="zoo" attr="barAtr" /> 
</root> 
+0

嗯我正在考慮使用連接並選擇,但這也適用。謝謝 ! – greenfeet

2

也許聯接會做到這一點:

var res = from e2 in list2 
     join e1 in list1 on e2.name equals e1.name into joined 
     from j in joined.DefaultIfEmpty() 
      select new Element 
      { 
       name = j.name, 
       attr = j.attr, 
       ChildElement = j.ChildElement 
      }; 
+0

這不適合一對夫婦的原因有:錯誤的語法爲 「左連接」,e1.name應該是e1.Attribute( 「名稱」)值,這不是你如何創建一個新的XElement。 – greenfeet