Converting value to nullable int using linq to xml

I am trying to catch, then convert an empty XML element value to null using Linq to XML.

This works great when a value for employee_count is supplied:

var companies = from a in xmlDoc.Descendants("company")
select new company
{
company_id = int.Parse(a.Attribute("company_id").Value),
employee_count = int.Parse(a.Element("employee_count").Value)
};

I have tried the following modifications to the query to catch empty values to no avail:
employee_count = a.Element("employee_count").IsEmpty ? (int?)a.Element("employee_count") : null,
employee_count = (int?)a.Element("employee_count") ?? null,
employee_count = a.Element("employee_count").IsEmpty ? (int?)null : int.Parse(a.Element("employee_count").Value),
 employee_count = (int?)a.Element("employee_count"),

The error is always:

System.FormatException: Input string was not in a correct format.
Any help, tips or pointers would be greatly appreciated.

Thanks,
Jeff
jptrueAsked:
Who is Participating?
 
tovvenkiCommented:
Hi,
one workaround I think will work is this

 
employee_count = isNum(a.Element("employee_count").Value)? Convert.ToInt32(a.Element("employee_count").Value):0


public static bool isNum(String s)
        {
            try {
                Convert.ToInt32(s);
        }
        catch (FormatException nfe) {
            return false;
        }
        return true;
        }

see if this works for you

Thanks and regards,
Venki
0
 
robastaCommented:
Int.parse expects a string,

have you tried:
employee_count = int.Parse(a.Element("employee_count").Value.ToString())
0
 
jptrueAuthor Commented:
Thank you robasta
Yes, I did try using int.Parse, however, if the string value is empty it will throw an error.

Jeff
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
jptrueAuthor Commented:
Thanks rkworlds,
I saw those sites during my initial research, but was able to work them into a solution that worked to a nullable int.

Thanks,
Jeff
0
 
tovvenkiCommented:
Hi,
try using Convert.Toint32 this will return 0 if the passed argument is null.
check this for difference between int.parse and convert.toint
http://www.dotnetspider.com/resources/1812-Difference-among-Int-Parse-Convert-ToInt.aspx

Thanks and regards,
Venki
0
 
jptrueAuthor Commented:
Thanks tovvenki,
I like your thinking! However, Convert.Toint32 did not work. Still getting the error.

Thanks,
Jeff
0
 
tovvenkiCommented:
what error are you getting. can you place a breakpoint and see what data is getting returned by the element.

Thanks and regards,
Venki
0
 
tovvenkiCommented:
because if you pass anything other than integer value, it will throw FormatException.
0
 
jptrueAuthor Commented:
Venki,

The error is below.
I cannot add a breakpoint as the code is a linq query.

Thanks,
Jeff

System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Convert.ToInt32(String value)
   at compile.<WriteAgencyRecordsToDatabase>b__18(XElement a) in c:\Inetpub\wwwroot\xml_compile_com\trunk\website\App_Code\compile.cs:line 388
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at System.Data.Linq.Table`1.InsertAllOnSubmit[TSubEntity](IEnumerable`1 entities)
   at compile.WriteRecordsToDatabase(String strXMLPath, HttpContext objContext) in c:\Inetpub\wwwroot\xml_compile_com\trunk\website\App_Code\compile.cs:line 435
   at compile.PutAgencyRecords(String EncryptedUsername, String EncryptedPassword, String strXML) in c:\Inetpub\wwwroot\xml_compile_com\trunk\website\App_Code\compile.cs:line 231
0
 
robastaCommented:
int temp;
var companies = from a in xmlDoc.Descendants("company")
select  new company
{
company_id = int.Parse(a.Attribute("company_id").Value),
employee_count  = int.TryParse(a.Element("employee_count").Value) ? int.Parse(a.Element("employee_count").Value) : new int?();
};

//tryparse will return TRUE if valid int, FALSE if not, then we use shorthand to assign value to employee_count
0
 
jptrueAuthor Commented:
In addition, I know that the value in the XML element is an empty string. Using Linq to XML I need to catch the empty string and pass a NULL value to the database.

Thanks,
Jeff
0
 
robastaCommented:
Update, use the attached code:

int temp;
var companies = from a in xmlDoc.Descendants("company")
select  new company
{
company_id = int.Parse(a.Attribute("company_id").Value),
employee_count  = int.TryParse(a.Element("employee_count").Value,temp) ? int.Parse(a.Element("employee_count").Value) : new int?();
};

Open in new window

0
 
tovvenkiCommented:
yeah, I am sorry I missed that, my mistake.
Just for testing can you change employee count to a string and see what is getting returned by element.
you will get formatexception only when the data passed is not correct.

Thanks and regards,
Venki
0
 
jptrueAuthor Commented:
Robasta,

Unfortunately, Visual Studio says TryParse has some invalid arguments when using your code.

Thanks again,
Jeff
0
 
jptrueAuthor Commented:
Venki,
This XML works great:
<employee_count><![CDATA[22]]></employee_count>

This throws an error:
<employee_count><![CDATA[]]></employee_count>

So does this:
<employee_count><![CDATA[ttt]]></employee_count>

Thanks,
Jeff
0
 
robastaCommented:
int temp;
var companies = from a in xmlDoc.Descendants("company")
select  new company
{
company_id = int.Parse(a.Attribute("company_id").Value),
employee_count  = int.TryParse(a.Element("employee_count").Value,temp) ? int.Parse(a.Element("employee_count").Value) : new int?();
};

0
 
jptrueAuthor Commented:
This was my closes attempt:
employee_count = a.Element("employee_count").IsEmpty ? (int?)null : int.Parse(a.Element("employee_count").Value),

IsEmpty works great at catching the empty string, however, I cannot get it to accept the first option:
(int?) null

I even tried (int?)0 and I still get the format error.

Thanks,
Jeff
0
 
robastaCommented:
employee_count = a.Element("employee_count").IsEmpty ? new int?() :  int.Parse(a.Element("employee_count").Value)
0
 
jptrueAuthor Commented:
Thanks again Robasta,
Unfortunately, it did not work... seems to me like it should however.

Jeff
0
 
jptrueAuthor Commented:
Venki,
That did indeed work!
You Rule!

Thank you.

And Robasta, thank you for all of your suggestions, as well.

Jeff
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.