XE2 XML Attribute can't convert to double
-
12-06-2021 - |
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
La 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);