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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

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
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jptrueAuthor Commented:
Venki,
That did indeed work!
You Rule!

Thank you.

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

Jeff
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.