XML to Linq and Optional fields

  • Thread starter Thread starter Jon
  • Start date Start date
J

Jon

Hi All,

I'm trying to parse an XML document that has optional fields.

Eg.

<parts>
<part>
<id>1</id>
<description>Item 1</description>
<length>34.5</length>
<qty>3</qty>
</part>
<part>
<id>2</id>
<description>Item 2</description>
<qty>4</qty>
</part>
</parts>

A part can sometimes have a length field.

I am parsing this with ..

var parts = from p in xmlFile.Elements("parts").Elements("part")
select new
{
Id = (int)p.Element("id"),
Description =
(string)p.Element("description"),
Qty = (float)p.Element("qty"),
Length =
(float)p.Element("length")
};


I would like the Length set to 0 if it does not exist in the XML - How can I
acheive this?
 
I may have oversimplified in my previous example..

I am trying to find the total number of each of the parts, grouped by ID and
Length. This is proving difficult, because Length is an optional field.

On first parsing the XML file, it would be nice to set the Length to 0,
unless someone can suggest a better way.



class Part
{
public int Id { get; set; }
public string Description { get; set; }
public float Qty { get; set; }
public float Length { get; set; }
}

class Program
{
static void Main(string[] args)
{
XDocument xmlFile = XDocument.Load(@"c:\xml\300.xml");

IEnumerable<Part> parts = from p in
xmlFile.Elements("parts").Elements("part")
select new Part
{
Id = (int)p.Element("id"),
Qty = (float)p.Element("qty"),
Length =
(float)p.Element("length")
};

var partsList = from p in parts
group p by new { p.Id, p.Length } into g
select new
{
Name = g.Key.Id,
Length = g.Key.Length,
Qty = g.Sum(o => o.Qty)
};
}
}
 
Jon said:
var parts = from p in xmlFile.Elements("parts").Elements("part")
select new
{
Id = (int)p.Element("id"),
Description =
(string)p.Element("description"),
Qty = (float)p.Element("qty"),
Length =
(float)p.Element("length")
};


I would like the Length set to 0 if it does not exist in the XML - How
can I acheive this?

You can cast the XElement to Nullable<float> (also written as float?)
and then use the ?? operator as follows:

XDocument doc = XDocument.Load(@"..\..\XMLFile2.xml");
var parts = from p in doc.Element("parts").Elements("part")
select new
{
Id = (int)p.Element("id"),
Description = (string)p.Element("description"),
Qty = (float)p.Element("qty"),
Length = (float?)p.Element("length") ?? 0
};
 
Martin Honnen said:
You can cast the XElement to Nullable<float> (also written as float?) and
then use the ?? operator as follows:

XDocument doc = XDocument.Load(@"..\..\XMLFile2.xml");
var parts = from p in doc.Element("parts").Elements("part")
select new
{
Id = (int)p.Element("id"),
Description =
(string)p.Element("description"),
Qty = (float)p.Element("qty"),
Length = (float?)p.Element("length") ?? 0
};


Thanks Martin,

Thats exactly what I was after.
 
Back
Top