C#Linq XML GroupBy OrderBy get count

时间:2016-08-18 14:17:16

标签: c# xml linq

我有这个xml结构,我需要非空工作和home元素的计数,groupby Country属性,然后orderby country属性。

像Dictionary>之类的东西,但我用linq表达式失败了。目前,列表仅被过滤,groupby和orderby。缺少部分是计数非空工作和家庭元素。 是否可以在查询中进行大量修改,或者在查询列表后使用?

XMLFILE

<?xml version="1.0" encoding="utf-8"?>
<Root>
    <Region ID="NA">
        <Name>QWERTZ</Name>
        <Country ID="1">
            <Facility Name="1">
                <Department Name="1">
                    <Member Name="1">
                        <Home>555-666</Home>
                        <Work>111-666</Work>
                    </Member>
                </Department>
            </Facility>
        </Country>      
    </Region>
        <Region ID="CHINA">
        <Name>ASDF</Name>
        <Country ID="2">
            <Facility Name="2">
                <Department Name="2">
                    <Member Name="2">
                        <Home>111-222</Home>
                        <Work>111-222</Work>
                    </Member>
                </Department>
            </Facility>
        </Country>      
    </Region>
    <Region ID="EU">
        <Name>ASDF</Name>
        <Country ID="3">
            <Facility Name="3">
                <Department Name="1">
                    <Member Name="1">
                        <Home>111-222</Home>
                        <Work></Work>
                    </Member>
                </Department>
            </Facility>
        </Country>      
    </Region>
</Root>

方法

 public static List<IGrouping<string,XElement>> getgrouped(string filename)
{
    XDocument xml = XDocument.Load(filename);

    return xml.Root
        .Descendants("Country")
        .GroupBy(x => (string)x.Attribute("ID").Value)
        .OrderBy(g => g.Key)
        .ToList();
}

1 个答案:

答案 0 :(得分:2)

对于每个后代,我投射一个具有国家ID和非空后代WorkHome元素数量的对象。然后我GroupBy并总结计数器。

xml.Root.Descendants("Country")
    .Select(element => new 
    {
        Id = (string) element.Attribute("ID").Value,
        NonEmptyWork = element.Descendants("Work")
                              .Count(w => !string.IsNullOrEmpty(w.Value)),
        NonEmptyHome = element.Descendants("Home")
                              .Count(w => !string.IsNullOrEmpty(w.Value))
    })
    .GroupBy(item => item.Id)
    .Select(g => new
    { 
        Id = g.Key, 
        NonEmptyWorkAmount = g.Sum(item => item.NonEmptyWork), 
        NonEmptyHomeAmount = g.Sum(item => item.NonEmptyHome)
    })
    .OrderBy(item => item.Id)
    .ToList();

将其输出为字典而不是ToList

    // Dictionary<string, YourType>
    .ToDictionary( key => key.Id, value => value);