Reputation: 15237
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
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
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