从linq获取不同的值到xml查询

时间:2013-08-19 07:34:00

标签: xml linq lambda no-duplicates

我正在获取一个csv文件并将其转换为XML,这很有效。

XML看起来像这样

<Root>
  <Player index="0">
    <Rank>
      <Level> A</Level>
      <Class>   1</Class>
    </Rank>
    <TopScores>
      <Lives>      1.0</Lives>
      <Kills>      0.0</Kills>
      <Time> 9:59:55</Time>
    </TopScores>
  </Player>
  <Player index="1">
    <Rank>
      <Level> A</Level>
      <Class>   2</Class>
    </Rank>
    <TopScores>
      <Lives>      1.2</Lives>
      <Kills>      0.0</Kills>
      <Time> 9:59:59</Time>
    </TopScores>
  </Player>
  <Player index="2">
    <Rank>
      <Level> A</Level>
      <Class>   3</Class>
    </Rank>
    <TopScores>
      <Lives>      1.2</Lives>
      <Kills>      0.0</Kills>
      <Time>10: 0: 3</Time>
    </TopScores>
  </Lives>
  <Player index="3">
    <Rank>
      <Level> A</Level>
      <Class>   1</Class>
    </Rank>
    <TopScores>
      <Lives>      0.9</Lives>
      <Kills>      0.0</Kills>
      <Time>10: 0: 8</Time>
    </TopScores>
  </Player>
</Root>

正如您所看到的,有一个重复的等级(等级1,等级0)。

我可以使用以下查询获取重复项的数量:

//The query below will return the duplicates so we can report the identities
//and the count of the number of duplicates.
var duplicates = playerData.Descendants("Rank")
                  .GroupBy(c => c.ToString())
                  .Where(g => g.Count() > 1)
                  .Select(g => g.First().Value);

我想得到所有'Rank'值的完整播放器数据,但是,如果有重复的'Rank'值,我想得到最后一次出现。因此,对于上面的XML数据,我应该只返回三组Player数据,当有重复时,它应该是具有最新时间或id的那一个。

要做到这一点,我尝试过:

var uPlays = playerData.Descendants("Player").Descendants("Rank")
                       .GroupBy(z => z.ToString())
                       .Select(b => b.Ancestors().First());

这为我提供了Rank的唯一值的所有Player数据,但当然它给了我遇到的第一个实例。我以为我只会将.First()更改为.Last(),但这只会给我三次重复的第一个值。

1 个答案:

答案 0 :(得分:2)

我会尝试这样的事情

var uPlays = playerData.Root.Elements("Player")
                      .GroupBy(c => c.Element("Rank").ToString())
                      .Select(g => g.Last());

或使用您的代码

var uPlays = playerData.Descendants("Player")
                       .Descendants("Rank")
                       .GroupBy(z => z.ToString())
                       .Select(b => b.Last().Parent);