Reputation: 2924
I am using XDocument
to make search on large XML files. When a user seeks a numeric value I get the value as decimal
, I do not differentiate between integers and floating point values. I know that assuming that the input from XML as a decimal is faulty but can not build a shorthand logic without writing extensive code.
User enters the value to seek on form as decimal and I save all filter values as a property by boxing in my SearchCriteria
object. Then I use the following code to find matching elements:
IEnumerable<XElement> allNodes = xDoc.Root.Descendants(root);
allNodes = (from ex in allNodes
where ex.Descendants(fieldName)
.Where(x => decimal.Parse(x.Value.Replace(".", ",")) == decimal.Parse(crit.SearchValue.ToString()))
.Count() > 0
select ex);
and get an exception for fields such as postal code, because it does not contain any decimal points.
What I want to do is to make search all values regardless of they contain a decimal point in it or not. But to accomplish this task I need to have a logic to decide whether to replace decimal point before comparison or not.
How can I do it in LinQ?
Regards.
Upvotes: 0
Views: 82
Reputation: 2781
Just rewrite condition:
ex
.Descendants(fieldName)
.Where(x => {
decimal dec;
return
decimal.TryParse(x.Value, NumberStyles.Number, culture, out dec) &&
/* other conditions and comparison with dec */;
}
If value cann't be parsed it's ignored.
EDIT: Use specific culture to parse numbers. It will be faster and will consume less memory. Also store parsed crit.SearchValue outside of the lambda.
Upvotes: 2
Reputation: 33149
There is no need to replace a "." by a ",". You can query for decimal.Parse(s,NumberStyles.Any, new CultureInfo("en")
and it will work.
You can make the code much more efficient by taking repeated stuff out that doesn't need to be repeated:
IEnumerable<XElement> allNodes = xDoc.Root.Descendants(root);
decimal match = decimal.Parse(crit.SearchValue.ToString());
CultureInfo culture = new CultureInfo("en");
allNodes = (from ex in allNodes where ex.Descendants(fieldName)
.Where(x => decimal.Parse(x.Value, culture) == match)
.Count() > 0 select ex);
Upvotes: 3