XDocument使用LINQ选择不同的元素

时间:2012-08-23 17:35:52

标签: linq-to-xml

我正在尝试获取一个独特的元素列表,但它总会返回所有内容。

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>

5 个答案:

答案 0 :(得分:7)

Distinct()不知道要比较XElement的哪一部分,因此它只会比较对象引用。由于所有XElements都是单独的对象,因此无论内容如何,​​都会将它们全部返回。

你要么必须定义一个允许它比较它们的IEqualityComparer(可能是首选的方法),要么只使用可以使用lambda的GroupB来比较实际值; < / p>

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>

答案 1 :(得分:0)

这对我有用:

var query = (from e in xml.Root.Elements("row").Elements("unit")
         select e).GroupBy(e => e.Value).Select(x => x.First());
编辑:哎呀 - 我忽略了'不同'的要求。使用 Joachim Isaksson 的lambda表达式修改上述答案。这是新的输出:

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

答案 2 :(得分:0)

选择e.Value,

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

答案 3 :(得分: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);
    }

答案 4 :(得分: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>