Parsing numbers from XML in a different culture

Microsoft dotNet.

All our xml data is stored in “en-US” format. For instance a number attribute would have a period for the decimal point:

<node decimalNum=“1.23” />

And dates like we do here in the USA:

<node today=“2011-12-17T00:00:00” />

However, our software has to support internationalization, and we’re following an unchangeable architectural decision to support other cultures - like “fr-FR”.

So simple code pieces like

string theNum = GetAttribute(“decimalNum”);
decimal myDecimal = decimal.Parse (theNum );

throw exceptions about incorrect formatting.

In short - what’s the way to say “parse this as en-US even though the culture is not en-US”?

Does your XML parser have a setLocale method? Or a .locale property?

Our XML parser is hand-rolled. It does not have a ‘setLocale’ or any equivalent.

The statements I provided above are basically how we do our parsing. We use an XPath iterator to get to a node, then tear the node apart attribute by attribute, using the target type’s default parser.

Online I see that the answer has to do with implementing an IFormatProvider. I’ve never done that. I bet googling will provide me with en-US FormatProviders.

More input welcome. I’m just kind of panicking because I came in on Saturday thinking I’d get caught up and I run into this thing none of us had thought of :o .

If you know the culture of the XML source, which you should if it is well-formed per the standard, then you call the Decimal.Parse overload which takes an IFormatProvider.

See Decimal.Parse Method (System) | Microsoft Learn for a pretty good example. There are corresponding pages for the other .Net versions at/after 2.0.

It’s not completely clear whether you mean that you have code executing under the fr-FR culture while parsing en-US data or vice versa. Assuming I got it forwards yo want this:

Quick version is you create a CultureInfo object from the known culture string (e.g. “en-US”), then you pass that object’s NumberFormat property to the Decimal.Parse method.


string theNum = GetAttribute("decimalNum");
decimal myDecimal = Decimal.Parse (theNum, new CultureInfo("en-US").NumberFormat);


Obviously it’d be more efficient to create the CultureInfo object just once & reuse it.

The date/time format you show there is culturally invariant. It’s explicitly designed to avoid all the cultural issues.

Sorry for triple-post, hit [enter] too soon.
You should be able to parse those dates using


string theDateTime = GetAttribute("someDateTime");
DateTime myDateTime = DateTime.Parse(theDateTime, CultureInfo.InvariantCulture.DateTimeFormat);

Oh. Sorry. Pre coffee answer. Is decimal your class, or is it an SDK class? (I assume it’s an SDK provided class, but if it were, I’d expect it to be Decimal instead. I haven’t done .NET programming in a few years, though)

What LSLGuy said.

Sorry for my rather discombobulated response. I wrote one version, posted, went back to hurriedly edit the goofs before time ran out, got it partly edited & time ran out, lather rinse repeat. And yes, I’m assuming the OP’s decimal class was really supposed to be .Net’s Decimal class.

But the code samples are correct for the case the OP says he has: parsing en-US or invariant data while your thread is running in any arbitrary culture.

I gotta stop hitting enter too soon …

If the OP needs to create any en-US- or invariant-formatted strings from other data types while running in a another culture, he’ll also need to use the same process in reverse by calling the .ToString() overload which takes an IFormatProvider of the desired result culture.

On the contrary, that looks pretty close to ISO 8601 to me. Wonderfully culture-neutral.

You should be able to do that, but you really should be abstracting datetime formats as part of your XML parser so that the only things that you actually work with in your business logic are strongly-typed objects such as DateTimes. Dates and times are used across all cultures - the problem is how they are WRITTEN. Your business logic shouldn’t have to know about that - that is part of the UI and IO.

http://www.globalnerdy.com/wordpress/wp-content/uploads/2010/05/icanhasstring.jpg (SFW, programming-oriented lolcat)

http://stackoverflow.com/questions/2349378/new-programming-jargon-you-coined/2444303#2444303 (SFW, programming discussion)

Thanks for the answers.

I’m new to the internationalization. So the CultureInfo class is an IFormatProvider.

So when reading in xml data, I’m just passing in a CultureInfo created for “en-US” regardless of the current culture.

Good catch on the culturally-neutral date format, too. Oops.

A CultureInfo class instance is *not *an IFormatProvider. Such an instance exposes various IFormatProviders as properties. One for numbers, one for dates, etc.

And to robert_columbia. Yes, your biz objects should be *exposing *these as native types. But something *within *the business class (or the data layer) has to deal with the translation to/from XML. And that’s what we’re discussing here.