Having trouble trying to turn an XDocument into an list of objects, in particular the Categories element. Below is a snippet of the XML which returns a list of shows in the following format.
<Show>
<Name>OLYMPIC GAMES</Name>
<Artist>OLYMPIC GAMES</Artist>
<OnSale>false</OnSale>
<DateOnSale>2011-03-11T00:00:00</DateOnSale>
<DoorsOpen>2012-12-31T10:00:00</DoorsOpen>
<Starts>2012-12-31T10:00:00</Starts>
<BespokeDate>25 July 2012 - 12 August 2012</BespokeDate>
<Status Code="3">SOLD OUT</Status>
<Categories>
<Category Id="190">OTHER</Category>
</Categories>
<Prices>
<Price Type="1">
<Status Code="24">ORDER</Status>
<FaceValue>0.00</FaceValue>
<BookingFee>0.00</BookingFee>
<TicketPrice>0.00</TicketPrice>
<Description>UNRESERVED</Description>
</Price>
</Prices>
<Venue Uri="/venues/">
<Name>Various venues</Name>
<Town></Town>
</Venue>
</Show>
Below is the classes I have created to model the XML data
public class Show {
public string Name { get; set; }
public string Artist { get; set; }
public bool OnSale { get; set; }
public DateTime DateOnSale { get; set; }
public DateTime DoorsOpen { get; set; }
public DateTime Starts { get; set; }
public string BespokeDate { get; set; }
public Status Status { get; set; }
public IEnumerable<Category> Categories { get; set; }
public Venue Venue { get; set; }
}
public class Status
{
public int Code { get; set; }
public string Description { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Venue
{
public string Uri { get; set; }
public string Name { get; set; }
public string Town { get; set; }
}
Below is the Linq to XML to create the Show objects
var shows = from s in xdoc.Descendants("Show")
where
s.Element("OnSale").Value.AsBool() != false
select
new Show {
Name = s.Element("Name").Value,
Artist = s.Element("Artist").Value,
OnSale = s.Element("Name").Value.AsBool(),
DateOnSale = s.Element("DateOnSale").Value.AsDateTime(),
DoorsOpen = s.Element("DoorsOpen").Value.AsDateTime(),
Starts = s.Element("Starts").Value.AsDateTime(),
BespokeDate = s.Element("BespokeDate").Value,
Status = new Status {
Code = s.Element("Status").Attribute("Code").Value.AsInt(),
Description = s.Element("Status").Value
},
Categories = (from c in s.Element("Categories").Elements("Category")
select new Category {
Id = s.Attribute("Id").Value.AsInt(),
Name = s.Value
}),
Venue = new Venue {
Name = s.Element("Venue").Element("Name").Value,
Town = s.Element("Venue").Element("Town").Value
}
};
Below is the code snippet to display a Show
foreach(var show in shows)
{
<p>
Name: @show.Name |
Status: @show.Status.Description |
Venue: @show.Venue.Name |
Categories: @string.Join(",", show.Categories.Select(x => x.Name))
</p>
}
The following error appears “Object reference not set to an instance of an object”, whenever attempting to display categories. From what I can see, every show has 1 or more categories.
Any ideas?
This is the problem:
You’re using
s.Attributeands.Valueinstead ofc.Attributeandc.Value.I would also suggest using the explicit conversion to
intinstead ofValue.AsInt():