Ahmad Mushtaq
Ahmad Mushtaq

Reputation: 1395

Help with creating an object out of xml data with nested elements

I have this xml:

<stop>
<code>2222222</code>
<code_short>E2217</code_short>
<name_fi>Konemies</name_fi>
<name_sv>Maskinbyggaren</name_sv>
<city_fi>Espoo</city_fi>
<city_sv>Esbo</city_sv>
<lines>
  <node>2010  1:Puolarmetsä</node>
  <node>2010K 1:Puolarmetsä</node>
  <node>2052  2:Hämevaara</node>
  <node>2103  1:Pohjois-Tapiola</node>
  <node>2103T 1:Pohjois-Tapiola</node>
  <node>2506  1:Pohjois-Tapiola</node>
  <node>2512A 2:Malmin asema</node>
  <node>2550  2:Itäkeskus, lait. 22</node>
  <node>5510  2:Vantaankoski</node>
</lines> </stop>

What I want is to use LINQ to create a List

where a Stop is:

public class Stop
{
    public string code { get; set; }
    public string shortCode { get; set; }
    public string name { get; set; }
    public string city { get; set; }

    public IList<string> lines { get; set; }

    public Stop()
    {
        lines = new List<string>();
    }
}

How can I achieve this with LINQ ?

This LINQ gives me a List of Stops

        XDocument xdoc = XDocument.Load("test.xml");

        var stop = (from node in xdoc.Element("response").Elements("node")
                    select new Stop
                    {
                        code = node.Element("code").Value,
                        shortCode = node.Element("code_short").Value,
                        name = node.Element("name").Value,
                        city = node.Element("city").Value
                    });

But how do I handle the lines ? Ideas ? Suggestions ?

Upvotes: 0

Views: 299

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500535

Something like this:

XDocument xdoc = XDocument.Load("test.xml");

var stop = (from node in xdoc.Descendants("stop")
            select new Stop
            {
                code = node.Attribute("code").Value,
                shortCode = node.Attribute("code_short").Value,
                name = node.Attribute("name").Value,
                city = node.Attribute("city").Value,
                lines = node.Element("lines")
                            .Elements("node")
                            .Select(x => (string) x)
                            .ToList()
            });

The above code also demonstrates an alternative way of converting an XElement to a string - using a cast instead of the .Value property. If the XElement is null, the result of the cast will be null, whereas the result of .Value will be an exception. If it's valid for the element to be missing, using .Value is good because it will cause an error as soon as the bad data is detected; for "optional" elements, the cast is an easy way to tolerate missing values.

Upvotes: 2

Related Questions