2012-08-23 35 views
1

我想獲得一個清晰的元素列表,但它總是返回所有內容。XDocument使用LINQ選擇不同的元素

XML:

<root> 
    <row> 
     <unit>CAN</unit> 
    </row> 
    <row> 
     <unit>KG</unit> 
    </row> 
    <row> 
     <unit>KG</unit> 
    </row> 
    <row> 
     <unit>PKT</unit> 
    </row> 
    <row> 
     <unit>CAN</unit> 
    </row> 
    <row> 
     <unit>PKT</unit> 
    </row> 
    <row> 
     <unit>KG</unit> 
    </row> 
</root> 

的Linq:

List<XElement> elements = (from e in xdoc.Descendants("row").Elements() 
    where e.Name.Equals("unit") 
    select e).Distinct().ToList(); 

預期輸出: 元素列表應包含3項

<unit>CAN</unit> 
    <unit>KG</unit> 
    <unit>PKT</unit> 

回答

7

Distinct()不知道比較一下XElement的一部分,所以它只會比較對象引用。由於所有XElements都是獨立的對象,無論內容如何,​​它都會將它們全部返回。

您必須定義一個IEqualityComparer,它允許它比較它們(可能是首選的方法),或者只是使用GroupBy,它可以使用一個lambda來允許它比較實際的值;

var elements = (from e in xdoc.Root.Elements("row").Elements("unit") 
       select e).GroupBy(x => x.Value).Select(x => x.First()); 

輸出:

<unit>CAN</unit> 
<unit>KG</unit> 
<unit>PKT</unit> 
+0

它的工作,我只需將.ToList()添加到最後。 ... x.First())。ToList(); – gangt

0

這個工作對我來說:

var query = (from e in xml.Root.Elements("row").Elements("unit") 
     select e).GroupBy(e => e.Value).Select(x => x.First()); 

編輯:哎呀 - 我忽略了'獨特'的要求。使用Joachim Isaksson的λ表達式修正上述答案。下面是新的輸出:

<unit>CAN</unit> 
<unit>KG</unit> 
<unit>PKT</unit> 
0

選擇e.Value,

from e in xdoc.Descendants("row").Elements() 
where e.Name.Equals("unit") 
select e.Value).Distinct().ToList(); 
0

我會組,採取的第一項各組:

XDocument doc = XDocument.Load("../../XMLFile1.xml"); 

    List<XElement> distinctUnits = 
     (from unit in doc.Root.Elements("row").Elements("unit") 
     group unit by (string)unit into g 
     select g.First()).ToList(); 

    foreach (XElement unit in distinctUnits) 
    { 
     Console.WriteLine(unit); 
    } 
0

這將得到的結果

 List<XElement> elements = new List<XElement>(); 

    foreach (var item in xdoc.Descendants().Where(c => c.Name == "unit").Select(c=>c)) 
     { 
      if (elements.Where(c => c.Value == item.Value).FirstOrDefault() == null) 
      { 
       elements.Add(item); 
      } 
     } 


    <unit>CAN</unit> 
    <unit>KG</unit> 
    <unit>PKT</unit>