mnsr
mnsr

Reputation: 12437

Flatten/Merge List using Linq

Lets say I have an XML file:

<locations>
    <country name="Australia">
        <city>Brisbane</city>
        <city>Melbourne</city>
        <city>Sydney</city>
    </country>
    <country name="England">
        <city>Bristol</city>
        <city>London</city>
    </country>
    <country name="America">
        <city>New York</city>
        <city>Washington</city>
    </country>
</locations>

I want it flattened to (this should be the final result):

Australia
Brisbane
Melbourne
Sydney
England
Bristol
London
America
New York
Washington

I've tried this:

var query = XDocument.Load(@"test.xml").Descendants("country")
    .Select(s => new
    {
        Country = (string)s.Attribute("name"),
        Cities = s.Elements("city")
            .Select (x => new { City = (string)x })
    });

But this returns a nested list inside query. Like so:

{ Australia, Cities { Brisbane, Melbourne, Sydney }},
{ England, Cities { Bristol, London }},
{ America, Cities { New York, Washington }}

Thanks

Upvotes: 2

Views: 194

Answers (2)

Risky Martin
Risky Martin

Reputation: 2521

Here's a way to do it with query syntax:

var query = from country in XDocument.Load(@"test.xml").Descendants("country")
            let countryName = new [] {(string)country.Attribute("name")}
            let cities = country.Elements("city").Select(x => (string)x)
            from place in countryName.Concat(cities)
            select place;

Upvotes: 4

ChaosPandion
ChaosPandion

Reputation: 78272

SelectMany should do the trick here.

var result = 
    XDocument.Load(@"test.xml")
    .Descendants("country")
    .SelectMany(e => 
        (new [] { (string)e.Attribute("name")})
        .Concat(
            e.Elements("city")
            .Select(c => c.Value)
        )
    )
    .ToList();

Upvotes: 5

Related Questions