var subset = from item in document.Descendants("Id")
where item.Value == itemId.ToString()
select new PurchaseItem() {
Id = int.Parse(item.Parent.Element("Id").Value),
Name = item.Parent.Element("Name").Value,
Description = item.Parent.Element("Description").Value,
Price = int.Parse(item.Parent.Element("Price").Value)
};
The structure of the XML is as follows:
<Items>
<Item>
<Id></Id>
<Name></Name>
<Description></Description>
<Price></Price>
</Item>
</Items>
Id, and price are both integer values. Name and description are strings.
I've found Linq to XML
great for what I've used it for, this is just a snippet. But, on the other hand I get the feeling it should or could be cleaner. The casting seems the most obvious issue in this snippet.
Any advice?
Actually it would be better IMO to cast than to call int.Parse
. Here's how I would write your query:
string id = itemId.ToString(); // We don't need to convert it each time!
var subset = from item in document.Descendants("Id")
where item.Value == id
let parent = item.Parent
select new PurchaseItem
{
Id = (int) parent.Element("Id"),
Name = (string) parent.Element("Name"),
Description = (string) parent.Element("Description"),
Price = (int) parent.Element("Price")
};
I assume that you have an "Items" node as well?
You could do something like this, assuming that you are loading the document using XElement.Load()
var subset = from item in document.Elements("Item")
where item.Element("Id").Value == itemId.ToString()
select new PurchaseItem() {
Id = int.Parse(item.Element("Id").Value),
Name = item.Element("Name").Value,
Description = item.Element("Description").Value,
Price = int.Parse(item.Element("Price").Value)
};
Not a lot better, but much easier to read!
In your example you can tidy up a little bit by finding the <Item/>
element rather than the <Id/>
to avoid getting the Parent
each time:
var subset = from item in document.Descendants("Item")
where item.Element("Id").Value == itemId.ToString()
select new PurchaseItem()
{
Id = int.Parse(item.Element("Id").Value),
Name = item.Element("Name").Value,
Description = item.Element("Description").Value,
Price = int.Parse(item.Element("Price").Value)
};
Consider writing a new constructor for PurchaseItem
that takes the XML element, so you can write:
select new PurchaseItem(item.Parent);