Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Zahlenwerte in XML (Decimalseparator) (https://www.delphipraxis.net/138610-zahlenwerte-xml-decimalseparator.html)

HenryE 13. Aug 2009 15:51


Zahlenwerte in XML (Decimalseparator)
 
Zahlenwerte in XML (Decimalseparator)


Hallo,

also ich bin mittlerweile ziemlich genervt von folgendem Problem. Dies sei evtl. auch als Warnung an Kollegen gemeint, die evtl. in die selbe Falle laufen.

Ich erstelle für die Verarbeitung von XML-Daten ein Schema und vergebe dort entsprechende Datentypen für die einzelnen Elemente.
Da nach W3C-Spezifikation Dezimalzahlen nur mittels Punkt als Trennzeichen angegeben werden dürfen, muß der Wert 1,34 als "1.34 angegeben werden. Sonst meckert eine Validierung gegen das Schema.

Aber jetzt kommt der dicke Hund. Wenn man nun mittels XML-Dokument oder die XML-Bindung auf ein XML-Dokument zugreifen möchte, dabei im System jedoch z.B. ein "," eingestellt ist (so wie im deutschen Schema eben), dann verwendet der Parser dieses Komma als Trennzeichen und wertet "1.34" als 134. Der Parser scheint sich also immer den Dezimal-Trenner aus den Gebietsschema-Einstellungen zu nehmen.
D.h., es wird kein Fehler geworfen, es wird halt eine völlig fasche Zahl zurückgeliefert.

Das Umbiegen der Gebietseinstellungen ist sicher keine gute Idee. Man benötigt also einen Weg, wie man dem Parser mitteilen kann, dass er ein "." als Dezimaltrenner benutzen soll.
Das einfachste wäre ja evtl. ein Processing-Anweisung oder irgendein Wert im XML-Dokument selbst. Nur habe ich da noch nichts finden können.
Ich habe lediglich in xsl das "xsl:decimal-format"-Konstrukt gefunden, aber das kann mir ja nicht wirklich weiterhelfen. Man abgesehen davon, dass ich nicht erst eine Transformation durchführen will.

Im Netzt habe ich nun schon viele Stunden gesucht und auch andere Beschreibungen des Problems gefunden. Jedoch war nie eine brauchbare (elegante) Lösung des Problems zu finden.
Nun dachte ich mir, dass Delphi-Nutzer (MSXML+Deutsches Gebietsschema) schließlich zur "Risikogruppe" für dieses Problem gehören müßten.

Vielen Dank für die Aufmerksamkeit
Grüße Henry

Systemumgebung: Delphi 2009 (alle Updates) + Vista

himitsu 13. Aug 2009 15:57

Re: Zahlenwerte in XML (Decimalseparator)
 
tja, XML ist ja als systemübergreifendes Austauschformat definiert und spricht demnach immer englisch,
damit es keine Probleme gibt ... leider arbeiten die delphiinternen Typumwandlungen mit den lokalen Spracheinstellungen.

leider muß ich zugeben, daß es dafür auch in meiner Lib noch keine "richtige" Lösung gibt, vorallem da dort die Werte auch mal via Variant ausgetauscht werden und demnach die Umwandlung über Delphi und dessen geladene Spracheinstellungen laufen :wall:

Namenloser 13. Aug 2009 16:07

Re: Zahlenwerte in XML (Decimalseparator)
 
Ich weiß nicht, ob das für dich eine "elegeante" Lösung ist, aber zumindest ist sie einfach:
Delphi-Quellcode:
DecimalSeparator := '.';

himitsu 13. Aug 2009 16:13

Re: Zahlenwerte in XML (Decimalseparator)
 
Zitat:

Zitat von NamenLozer
Ich weiß nicht, ob das für dich eine "elegeante" Lösung ist, aber zumindest ist sie einfach:

einfach son nd dann läuft mit dem XML vieles besser,
aber dafür spricht dann deine restliche Anwendung auch plötzlich (etwas) englisch.

z.B. möchte nmun FloatToStr einen Punkt statt Komma, Format nimmt nun auch einen Punkt usw.
heißt: da wo es .B. um Usereingaben geht, wird nun nicht mehr die Systemeinstellung genommen.

HenryE 13. Aug 2009 16:14

Re: Zahlenwerte in XML (Decimalseparator)
 
Mit SysUtils.DecimalSeparator habe ich natürlich bereits experimentiert. Jedoch nur mit Teilerfolg. Beim Schreiben von Knoten und nachfolgendem Speichern werden zumindest Punkte ins XML geschrieben. Beim Lesen kommt aber immer noch Quatsch heraus.
Komisch, jetzt bin ich erst recht verwirrt.

Eigentlich will ich die XML-Bindung verwenden, da diese ja einen riesigen Komfort bietet. Da ist es ja genau Sinn und Zweck, nicht noch eigene Umwandlungsrutinen dazwischen zu schalten, sondern typsicher auf die Elemente zuzugreifen.

himitsu 13. Aug 2009 16:21

Re: Zahlenwerte in XML (Decimalseparator)
 
also bei meinem himXML gibt es derzeit zumindestens keine Probleme, wenn es auf Systemen mit gleichen Spracheinstellungen verwendet wird, da ihm Punkt und Komma egal sind ... allerdings landen dann auf einem deutschen System dann natürlich die Werte mit Komma in der Datei :oops:

HenryE 13. Aug 2009 16:30

Re: Zahlenwerte in XML (Decimalseparator)
 
Ohne XML-Bindung hatte ich früher auch eine eigene Umwandlungsrutine eingebaut, die selbst geschaut hat, ob im String ein Punkt oder Komma vorhanden ist. Aber nun möchte ich die Vorzüge der XML-Bindung (die im Grunde echt cool ist, insbesondere wenn mann über das Schma eine echte Typisierung der Elemente reinbringt) nutzen und muß zuverlässig schema-konforme XML-Dateien erzeugen, weil diese noch von Fremdsystemen weiterverarbeitet werden sollen.

Was mich wundert: da müssen doch schon einige in diese Falle getappt sein, da man sie unter Umständen gar nicht bemerkt.
Aus 1.44 wir 144, aus 1.3872833 immerhin schon 13872833. Das ist doch ein Scheunentor zu allerlei Unfug! :-)

Namenloser 13. Aug 2009 16:56

Re: Zahlenwerte in XML (Decimalseparator)
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von NamenLozer
Ich weiß nicht, ob das für dich eine "elegeante" Lösung ist, aber zumindest ist sie einfach:

einfach son nd dann läuft mit dem XML vieles besser,
aber dafür spricht dann deine restliche Anwendung auch plötzlich (etwas) englisch.

z.B. möchte nmun FloatToStr einen Punkt statt Komma, Format nimmt nun auch einen Punkt usw.
heißt: da wo es .B. um Usereingaben geht, wird nun nicht mehr die Systemeinstellung genommen.

Schon klar, aber immer noch besser als wenn falsche Werte eingelesen werden. Man könnte auch im restlichen Teil des Programms die Funktion mit dem zweiten Parameter FormatSettings aufrufen, um das zu umgehen.

HenryE 13. Aug 2009 17:03

Re: Zahlenwerte in XML (Decimalseparator)
 
Das Ganze muß doch ohne das munuelle Aufrufen von eigenen Umwandlungsrutinen zu lösen sein, da ansonsten die XML-Bindung so nicht verwendet werden kann. Auf die kann und will ich nicht verzichten.
Übrigens scheint es hier
https://forums.codegear.com/thread.j...20509&tstart=0
um das selbe Problem zu gehen. Aber eine Lösung kann ich dort auch noch nicht finden. Im Prinzip muß der Parser ja nur wissen, dass er ein bestimmtes Zeichen benutzen soll, aber eben nicht das, was im System-Gebietsschema hinterlegt ist.

Grüße Henry

alzaimar 13. Aug 2009 17:08

Re: Zahlenwerte in XML (Decimalseparator)
 
Ich formatiere/konvertiere meine Float-Werte in/aus XML gnadenlos selbst. Eine bessere Idee habe ich auch nicht.

himitsu 13. Aug 2009 17:28

Re: Zahlenwerte in XML (Decimalseparator)
 
Zitat:

Zitat von alzaimar
Ich formatiere/konvertiere meine Float-Werte in/aus XML gnadenlos selbst. Eine bessere Idee habe ich auch nicht.

aus diesem Grund hab ich intern auch angefangen den Variant selber auseinander zunehmen und dort dann möglichst konforme Typumwandlungen vorzunehmen.
aber wenn man bedenkt, was alles so in einen Variant reinpaßt :freak:

HenryE 13. Aug 2009 17:28

Re: Zahlenwerte in XML (Decimalseparator)
 
Hm! Ich glaube, das Problem liegt in diesem Fall wirklich bei MS. Ich habe Fehlermeldungen gefunden, die im Zusammenhang mit BizTalk und XML genau das selbe Problem beschrieben.

HenryE 13. Aug 2009 17:33

Re: Zahlenwerte in XML (Decimalseparator)
 
Zitat:

aus diesem Grund hab ich intern auch angefangen den Variant selber auseinander zunehmen und dort dann möglichst konforme Typumwandlungen vorzunehmen
kann man sich denn elegant in die Variant-Typ-Umwandlungen einhängen. Irgendwie mittels Callback?
Auch wenn ich wirklich keine Lust darauf habe, aber vielleicht könnte das was für einen Würg-Around sein.
Aber ich glaube, dann würde ich eher mittels XSLT eine Umformung machen und dort den gerade aktuelle gültigen Decimal-Trenner einfügen.
Ich weiß auch nicht. Das ist ega so ein Gewurschtel. Das mag ich überhaupt nicht. :-)

himitsu 13. Aug 2009 17:48

Re: Zahlenwerte in XML (Decimalseparator)
 
Man könnte sich da zwar direkt in den Variant reinhängen, aber dann gibt es wieder das Problem, daß diese Umwandlung auch programmweit wirksam wäre und nicht nur im XML-Teil.

Ich hab es deßhalb so gelösßt, daß im XML die Umwandlung XML-String<>Variant manuell gemacht wird, also geschaut was in dem Variant drin steckt und dann entsprechende Umwabdlungen nur innerhalb der XML-Klasse vorgenommen werden.

HenryE 13. Aug 2009 17:53

Re: Zahlenwerte in XML (Decimalseparator)
 
Das scheint mir recht aufwendig zu sein. Irgendwie muß das anders gehen. Irgendwas muß mir da einfallen...
Aber Danke schonmal für Eure Anteilnahme.

Der schöne Günther 16. Dez 2013 13:26

AW: Zahlenwerte in XML (Decimalseparator)
 
Ganz bewusst buddele ich das Thema von 2009 wieder aus. Ich bin hilflos. Ich finde noch nicht mal einen QC-Eintrag. Im Emba-Forum ein Thema aus 2012.

Gab es genau die selbe Geschichte nicht neulich nochmal mit JSON? Ich bin immer noch ratlos, was ich jetzt tun muss, damit Kommazahlen als "3.14" und nicht "3,14" in meinem XML landen.

Zusammenfassung:
Delphi-Quellcode:
IXMLDocument::NodeValue
nimmt ein
Delphi-Quellcode:
OleVariant
entgegen welches im Falle einer Kommazahl direkt mit den globalen
Delphi-Quellcode:
FormatSettings
umgewandelt wird. Ich finde keine Möglichkeit, ein eigenes
Delphi-Quellcode:
TFormatSettings
-Objekt irgendwo reinzustecken.

Ich kann also nur die globalen FormatSettings anpassen? Gibt es irgendwo einen Bug-Report? Es kann doch nicht sein, dass hier ungültiges XML rauskommt :evil:

himitsu 16. Dez 2013 13:42

AW: Zahlenwerte in XML (Decimalseparator)
 
Im Prinzip müsste die Umwandlung dort explizit ein englischsprachisches FormatSettings benutzen.

Oder du wandelst die Zahl selber um. (FloatToStr + eigenes FormatSettings)

Der schöne Günther 16. Dez 2013 16:11

AW: Zahlenwerte in XML (Decimalseparator)
 
Müsste, ja. Tut sie aber nicht :roteyes:

Mal sehen, was sich mit einem Helper da bessern lässt. Ach warte, geht ja nicht für Interfaces (IXMLNode).

Ja, heute ist Stinkstiefel-Tag

Sir Rufo 16. Dez 2013 16:20

AW: Zahlenwerte in XML (Decimalseparator)
 
Eben weil Delphi-Referenz durchsuchenIXMLNode.NodeValue ein Delphi-Referenz durchsuchenOleVariant ist, nehme ich das Lesen (!) und Schreiben lieber selber in die Hand. Denn dort kann ja eben alles stehen.

Also warum nicht so wie bei Delphi-Referenz durchsuchenTCustomIniFile
Delphi-Quellcode:
TNodeValueHandler = class
  private
    FFormat : TFormatSettings;
  public
    procedure WriteString( Node : IXMLNode; const Value : string );
    procedure WriteFloat( Node : IXMLNode; const Value : Extended );
    ...
    function ReadString( Node : IXMLNode; const Default : string ) : string;
    function ReadFloat( Node : IXMLNode; const Default : Extended ) : Extended;
    ...
   end;

procedure TNodeValueHandler.WriteString( Node : IXMLNode; const Value : string );
begin
  Node.NodeValue := Value;
end;

procedure TNodeValueHandler.WriteFloat( Node : IXMLNode; const Value : Extended );
begin
  WriteString( Node, FloatToStr( Value, FFormat ) );
end;

function TNodeValueHandler.ReadString( Node : IXMLNode; const Default : string ) : string;
begin
  Result := VarToStrDef( Node.NodeValue, Default );
end;

function TNodeValueHandler.ReadFloat( Node : IXMLNode; const Default : Extended ) : Extended;
begin
  Result := StrToFloatDef( ReadString( Node, '' ), Default );
end;

Der schöne Günther 17. Okt 2014 11:00

AW: Zahlenwerte in XML (Decimalseparator)
 
Ich habe durch Zufall
Soap.XSBuiltIns.SoapFloatToStr(Value: double): string; gefunden. In der Unit gibt es noch mehr, wie beispielsweise auch XML-konforme Umwandlung von und in TDateTime :-)

Bei der Gelegenheit auch gleich einen Kreuzpfosten in Embarcaderos neuem Forum aufgemacht. Ich finde, das sollte nicht nötig sein. Wenn man sich den Code von TXMLNode.SetNodeValue ansieht, konvertieren die sogar ein "True" nach "true" damit es XML-conform ist. Aber Kommazahlen haben die irgendwie vergessen...

Dejan Vu 17. Okt 2014 12:27

AW: Zahlenwerte in XML (Decimalseparator)
 
Hab mir deinen Kreuzpfosten angeschaut: Das XML ist aber valide.
Code:
<rootNode>
  <invalidContent>3,14159265358979</invalidContent>
</rootNode>
Nur die *Intention* ist ja eine andere, nämlich die: Du hast ein Schema und willst die Delphi XML-Datenbindung verwenden.
Code:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="rootNode">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:float" name="invalidContent"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
Delphi-Quellcode:
Der Delphi-Code dazu:
IXMLRootNode = interface(IXMLNode)
    ['{323E65B5-3A1C-4937-8413-91430DC19316}']
    { Property Accessors }
    function Get_InvalidContent: Single;
    procedure Set_InvalidContent(Value: Single)
    { Methods & Properties }
    property InvalidContent: Single read Get_InvalidContent write Set_InvalidContent;
  end;

{ Forward Decls }

  TXMLRootNode = class;

{ TXMLRootNode }

  TXMLRootNode = class(TXMLNode, IXMLRootNode)
  protected
    { IXMLRootNode }
    function Get_InvalidContent: Single;
    procedure Set_InvalidContent(Value: Single);
  end;
Und wenn Du nun ausführst:
Delphi-Quellcode:
var
  node : IXMLRootNode;

begin
  node := NewrootNode;
  node.InvalidContent := Pi;
  memo1.Lines.text := node.XML;
end;
Hast Du -et voilá- ein XML, was nicht gegen das Schema validiert werden kann. Und *DAS* ist ein Bug.

Das geht natürlich auch mit Datumse. Is ja klar.

Der schöne Günther 17. Okt 2014 12:40

AW: Zahlenwerte in XML (Decimalseparator)
 
Ja, "XML not valid" ist falsch ausgedrückt. Es ist immer noch well formed, aber nicht mehr gegen ein Schema validierbar was hier einen Float erwartet.

Ich ändere das wohl noch, nicht dass mich da jemand falsch verstehen will :smile2:

Dejan Vu 17. Okt 2014 14:32

AW: Zahlenwerte in XML (Decimalseparator)
 
Nee, aber da wird immer so viel durcheinander gebracht und in diesem Hochspezialistenforum wollen wir doch bei dieser Kerntechnologie korrekte Bezeichnungen verwenden.

Vor allen Dingen ist man bei einer Hotline oder einem Supportforum wie bei Emba gerne darauf aus, solche Kinkerlitzchen zum Anlass zu nehmen, die Sache abzubügeln: "Wieso? Ist doch valide!" => kein Fehler => gelöscht.

mkinzler 17. Okt 2014 14:37

AW: Zahlenwerte in XML (Decimalseparator)
 
Hier ist aber nicht er EMBT Support. Anhand des Betreffs sollte eigentlich klar sein, was gemeint war.

Der schöne Günther 29. Okt 2014 10:15

AW: Zahlenwerte in XML (Decimalseparator)
 
Embarcaderos neues(?) Forum ist leider vollkommen tot, das interessiert dort niemanden.

Deshalb habe ich es in Embarcaderos neues QC eingetragen. Für den Fall dass es nicht als "as designed" abgestempelt wird gebe ich Bescheid wenn das Volk Voten darf :-)

Bernhard Geyer 29. Okt 2014 12:32

AW: Zahlenwerte in XML (Decimalseparator)
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1277828)
Embarcaderos neues(?) Forum ist leider vollkommen tot, das interessiert dort niemanden.

Was erwartest du. Die letzte Aktion eine Emba-Mitarbeiters war im Forum um 10:52 AM.
Das kann man wohl nicht als Tod bezeichnen wenn dein Eintrag nicht innerhalb von 2 Stunden angenommen wird ...

Der schöne Günther 29. Okt 2014 12:49

AW: Zahlenwerte in XML (Decimalseparator)
 
Der Eintrag im Forum war vor 11 Tagen (oder so) und ist immer noch das zweitneuste Thema in dem Bereich, das meinte ich.
Der QC-Report ist neu, das im Forum nicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz