Question

I have a XML node with attributes like this:

<pad name="E" x="2.5" y="7" drill="1.3"/>

When I assign the Attributes["x"] into a double I get the result 25, not 2.5 but without any complaints or errors.

To get a correct conversion I first have to assign the attribute to a string, replace the decimal '.' to a decimal ',' and then convert the string to a double. It is clearly that the Attribute["x"] can't convert but it doesn't say anything! (bug?!?)

Here is the code with faulty conversion:

double x = XMLNode->Attributes["x"];

This gives a faulty x of 25 instead of 2.5 and here is my work around:

String sd = XMLNode->Attributes["x"];
if (sd.Pos(".")) sd[sd.Pos(".")] = ',';
double x = sd.ToDouble();

This gives the correct value in x (2.5)

There MUST be a more simple way to do this!

// Thanks

Was it helpful?

Solution

XML attributes are arbitrary string values if you are not using an XSD to coherce the data, such as with the IDE's XML Data Binding wizard. The Attributes[] property returns an OleVariant, which in this case is going to contain a System::String in it. When a System::String is converted to a double using the OleVariant's double conversion operator or the String::ToDouble() method, the conversion uses the global SysUtils::DecimalSeparator variable, which is initialized using your PC's locale settings, which are clearly using the , character as a decimal separator instead of the . character. XML has no way of knowing that locale setting.

Since you are using a modern version of C++Builder, you can use the overloaded version of the StrToFloat() function that lets you pass in a TFormatSettings record as input. You can then specific . as the TFormatSettings::DecimalSeparator to use for the conversion, eg:

TFormatSettings fmt = TFormatSettings::Create();
fmt.DecimalSeparator = '.';
double x = StrToFloat(XMLNode->Attributes["x"], fmt); 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top