Search code examples
xmldelphidelphi-10.1-berlinregional-settingstxmldocument

How to read a floating point value correctly from an XML file independently from regional settings?


I am reading a floating point attribute value from a node in an XML file with TXMLDocument:

<MyApp_Favorites version="1.0">

...with this statement:

var
  ThisRootNode: IXMLNode;
  ThisVersion: Single;

// ...

ThisVersion := ThisRootNode.Attributes['version'];
CodeSite.Send('ThisVersion', ThisVersion);

However, on my German language system I get this version value:

ThisVersion = 10,00

...as in my regional settings the comma "," is defined as decimal separator and not the dot "." as in the XML file. But with an English language regional setting - where the dot is most probably defined as decimal separator setting - the result will be correct as "1.0".

So how can I make sure that independently from the regional setting the read VALUE of 1.0 will be always the same? (Reading the version value as string and then convert it to float doesn't seem to be a very elegant method).


Solution

  • A floating point number isn't a sensible format for a version number, rounding errors and lack of representability being major drawbacks. Consider using a record with integers to define the version numbers.

    program Project1;
    {$APPTYPE CONSOLE}
    
    uses
      SysUtils, StrUtils, Types;
    type    
    TVersion = record
      private
        procedure Set_AsString(AVersion : string);
        function Get_AsString: String;
      public
        Major: Integer;
        Minor: Integer;
        property AsString: String read Get_AsString write Set_AsString;
    end;    
    
    function TVersion.Get_AsString: String;
    begin
      Result := Format('%d.%d', [Major, Minor]);
    end;
    
    procedure TVersion.Set_AsString(AVersion: string);
    var
      split : TStringDynArray;
    begin
      split := SplitString(AVersion, '.');
      Major := StrToInt(split[0]);
      Minor := StrToInt(split[1]);
    end;
    
    var
      v1, v2 : TVersion;
      s : string;
    begin
      v1.Major := 12;
      v1.Minor := 34;
      WriteLn(v1.AsString);
    
      s := v1.AsString;
      v2.AsString := s;
    
      WriteLn(v2.AsString);
      ReadLn;
    end.