J86
J86

Reputation: 15237

Parsing elements in second nesting level of XML file

I am working on a little executable application. The application is simply an XML Parser that will parse an XML file and store the data parsed into a database. So the XML file that this application will do its magic on has the following structure:

<?xml version="1.0" encoding="utf-8"?>
<events>
    <event>
        <book>Felicity Fly</book>
        <author>Christina Gabbitas</author>
        <bookImgUrl>http://www.whsmith.co.uk/Images/Products\957\255\9780957255203_t_f.jpg</bookImgUrl>
        <info>Christina Gabbitas will be signing copies of her new book, Felicity Fly. Books should be bought from WHSmith. Proof of purchase may be necessary</info>
        <date>25 May 2013</date>
        <startTime>10:30</startTime>
        <location>
            <name>WHSmith Brent Cross</name>
            <address>Brent Cross Shopping Centre</address>
            <city>London</city>
            <county/>
            <postcode>NW4 3FB</postcode>
            <tel>020 8202 4226</tel>
        </location>
    </event>
    <!-- many more events as above here -->
</events>

And here is what I have so far in terms of code parsing logic.

namespace XMLParser
{
    public class Parser
    {
        static void Main(string[] args)
        {
            var path_to_xml = "data.xml";
            var xdoc = XDocument.Load(path_to_xml);
            var events = from e in xdoc.Descendants("event")
                         select new {
                             Book = (string)e.Element("book").Value,
                             Author = (string)e.Element("author").Value,
                             BookImgUrl = (string)e.Element("bookImgUrl").Value,
                             Info = (string)e.Element("info").Value,
                             Date = (string)e.Element("date").Value,
                             Time = (string)e.Element("startTime").Value,
                             // stuck here
                         }
        }
    }
}

I get stuck where I get to the Location node, I don't know how to parse the location related information.

Upvotes: 0

Views: 1681

Answers (2)

Tom Blodget
Tom Blodget

Reputation: 20782

Assuming you want to keep the location fields nested...

       var xdoc = XDocument.Parse(xml);
       var events = from e in xdoc.Descendants("event")
                     select new {
                         Book = e.Element("book").Value,
                         Author = e.Element("author").Value,
                         BookImgUrl = e.Element("bookImgUrl").Value,
                         Info = e.Element("info").Value,
                         Date = e.Element("date").Value,
                         Time = e.Element("startTime").Value,
                         Location = new {
                             Name = e.Element("location").Element("name").Value,
                             Address = e.Element("location").Element("address").Value,
                             City = e.Element("location").Element("city").Value,
                             County = e.Element("location").Element("county").Value,
                             Postcode = e.Element("location").Element("postcode").Value,
                             Tel = e.Element("location").Element("tel").Value
                         }
                     };

            Console.WriteLine(events.First().Location.City);

Upvotes: 1

MarcinJuraszek
MarcinJuraszek

Reputation: 125630

You have to decide whether you're using (string)XElement casting or XElement.Value property.

(string)e.Element("book").Value compiles and works fine, but XElement.Value is already a string, so casting it to string is pointless. I suggest using (string)XElement, because it won't cause NullReferenceException when Element won't be find.

You can also use let keyword to get e.Element("location") only once, and then use it to get all Location-related values:

var xdoc = XDocument.Parse(xml);
var events = from e in xdoc.Descendants("event")
             let l = e.Element("location")
             select new {
                 Book = (string)e.Element("book"),
                 Author = (string)e.Element("author"),
                 BookImgUrl = (string)e.Element("bookImgUrl"),
                 Info = (string)e.Element("info"),
                 Date = (string)e.Element("date"),
                 Time = (string)e.Element("startTime"),
                 Location = new {
                     Name = (string)l.Element("name"),
                     Address = (string)l.Element("address"),
                     City = (string)l.Element("city"),
                     County = (string)l.Element("county"),
                     Postcode = (string)l.Element("postcode"),
                     Tel = (string)l.Element("tel")
                 }
             };

Console.WriteLine(events.First().Location.City);

Upvotes: 1

Related Questions