Hey Guys...

I've got a bit of a fiddly problem...

I have an XML doc in the following format:

<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20130</Member>
</row>
<row>
<DNOrPattern>1015</DNOrPattern>
<HuntList>HL-1104 B Ltd</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20110</Member>
</row>
<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20110</Member>
</row>
<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1104 C Capital</LineGroup>
<RNAReversionTimeout>12</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>11048624</Member>
</row>
<row>
<DNOrPattern>1015</DNOrPattern>
<HuntList>HL-1104 B Ltd</HuntList>
<LineGroup>LG-1104 B</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20132</Member>
</row>

I want to read it into some sort of heirarchy along these lines....

DNOrPattern
HuntList
LineGroup
Members

So from the data above i end up with the data in this logical heirarchy i.e. for each DNorPattern i can expand to see the hunt list then expand the huntlist to see the linegroups then expand the linegroups to see the members! (I'm putting this in code to keep the indentation)

DNOrPattern: 1015
	HuntList: HL-1104 B Ltd
			LineGroup: LG-1000-COREVM1
					Member: 20110

			LineGroup: LG-1104 B	
					Member: 20132


DNOrPattern: 0444
	HuntList: HL-1104 C Capital
			LineGroup: LG-1000-COREVM1
					Member: 20110
					Member: 20130

			LineGroup: LG-1104 C Capital
					Member: 11048624

Hope that makes some sense....

I think Linq should be able to do this but i dont know where to begin really...

this is how i've started (the table is stored in StoreSoap.SoapHuntDoc as an XDocument)

var rows = from row in StoreSoap.SoapHuntDoc.Descendants("row")
                        select new
                        {
                            Pilot = row.Element("DNOrPattern").Value,
                            HuntList = row.Element("HuntList").Value,
                            LineGroup = row.Element("LineGroup").Value,
                            RNA = row.Element("RNAReversionTimeout").Value,
                            DistributionAlgorithm = row.Element("DistributionAlgorithm").Value,
                            Member = row.Element("Member").Value,
                        };

Edited 6 Years Ago by danturn: n/a

That's some crazy multi-level grouping that you need to do, more than likely. And it's possible. Run the following sample based upon what you've already done:

string xml = @"<rows><row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20130</Member>
</row>
<row>
<DNOrPattern>1015</DNOrPattern>
<HuntList>HL-1104 B Ltd</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20110</Member>
</row>
<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1000-COREVM1</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20110</Member>
</row>
<row>
<DNOrPattern>0444</DNOrPattern>
<HuntList>HL-1104 C Capital</HuntList>
<LineGroup>LG-1104 C Capital</LineGroup>
<RNAReversionTimeout>12</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>11048624</Member>
</row>
<row>
<DNOrPattern>1015</DNOrPattern>
<HuntList>HL-1104 B Ltd</HuntList>
<LineGroup>LG-1104 B</LineGroup>
<RNAReversionTimeout>4</RNAReversionTimeout>
<DistributionAlgorithm>Top Down</DistributionAlgorithm>
<Member>20132</Member>
</row></rows>";

XDocument document = XDocument.Parse(xml);

var rows = from row in document.Descendants("row")
           select new
           {
               Pilot = row.Element("DNOrPattern").Value,
               HuntList = row.Element("HuntList").Value,
               LineGroup = row.Element("LineGroup").Value,
               RNA = row.Element("RNAReversionTimeout").Value,
               DistributionAlgorithm = row.Element("DistributionAlgorithm").Value,
               Member = row.Element("Member").Value,
           };

var groupings = (from row in rows
                 group row by row.Pilot into pilotgroup
                 select new
                     {
                         Pilot = pilotgroup.Key,
                         Huntlists = (from row in pilotgroup
                                      group row by row.HuntList into huntgroup
                                      select new
                                      {
                                          Huntlist = huntgroup.Key,
                                          LineGroups = (from row in huntgroup
                                                        group row by row.LineGroup into linegroup
                                                        select new
                                                        {
                                                            LineGroup = linegroup.Key,
                                                            Members = (from row in linegroup
                                                                       select new
                                                                       {
                                                                           Member = row.Member
                                                                       }).ToList()
                                                        }).ToList()
                                      }).ToList()
                     }).ToList();

foreach (var grouping in groupings)
{
    Console.WriteLine("DNOrPattern: {0}", grouping.Pilot);
    foreach (var huntlist in grouping.Huntlists)
    {
        Console.WriteLine("\tHuntlist: {0}", huntlist.Huntlist);
        foreach (var linegroup in huntlist.LineGroups)
        {
            Console.WriteLine("\t\tLineGroup: {0}", linegroup.LineGroup);
            foreach (var member in linegroup.Members)
            {
                Console.WriteLine("\t\t\tMember: {0}", member.Member);
            }
        }
    }
}

Console.Read();

The output:

DNOrPattern: 0444
        Huntlist: HL-1104 C Capital
                LineGroup: LG-1000-COREVM1
                        Member: 20130
                        Member: 20110
                LineGroup: LG-1104 C Capital
                        Member: 11048624
DNOrPattern: 1015
        Huntlist: HL-1104 B Ltd
                LineGroup: LG-1000-COREVM1
                        Member: 20110
                LineGroup: LG-1104 B
                        Member: 20132

Edited 6 Years Ago by apegram: n/a

(Split this from last post)

An alterate way to perform the grouping that will not create the same hierarchy in code but can be used to generate the same output, is to do something like this:

var groupings2 = (from row in rows
                  group row by new { row.Pilot, row.HuntList, row.LineGroup }
                      into rowgroup
                      select new
                      {
                          Pilot = rowgroup.Key.Pilot,
                          Huntlist = rowgroup.Key.HuntList,
                          LineGroup = rowgroup.Key.LineGroup,
                          Members = (from row in rowgroup select row.Member).ToList()
                      }).OrderBy(g => g.Pilot).ThenBy(g => g.Huntlist).ThenBy(g => g.LineGroup).ToList();

string pilot = string.Empty;
string hunt = string.Empty;

foreach (var grouping in groupings2)
{
    if (grouping.Pilot != pilot)
    {
        Console.WriteLine("DNOrPattern: {0}", grouping.Pilot);
        pilot = grouping.Pilot;
        hunt = string.Empty;
    }

    if (grouping.Huntlist != hunt)
    {
        Console.WriteLine("\tHuntlist: {0}", grouping.Huntlist);
        hunt = grouping.Huntlist;
    }
    Console.WriteLine("\t\tLineGroup: {0}", grouping.LineGroup);
    foreach (var member in grouping.Members)
        Console.WriteLine("\t\t\tMember: {0}", member);
}

You see that here you create grouping rows with Pilot, Huntlist, and LineGroup together and then a list of members. You have to take a bit more control to print your header information between iterations.

And truthfully, if you did it that way, you could do it without grouping at all by sorting your data on multiple values and monitoring changes on pilot, huntlist, and linegroup values.

Comments
Super effort

wowza,

That's awesome.

the first option is what i need... the output isnt console, it needs to get banged into a table so i need the heirarchy in place.

I had absolutely no idea how to approach this so thank you very much!

some of the data structures in cisco call manager are quite complicated and the recipient of the data needs it in a completely unrelated format.

yipee!

This question has already been answered. Start a new discussion instead.