![]() |
ClientDataSet mit XML und UTF8
Hallo,
ich verwende XE3 und UTF8-kodierte XML Dateien und lese diese Mittels XMLDocument, XMLTransformProvider und ClientDataSet ein, sodaß alle Data-Aware Komponenten so funktionieren, als würden die Daten aus einer Datenbank stammen (XML ist ja dann quasi eine). Für den XMLransformProvider wurden die entsprechenden Transformations-Dateien (XTR) mit XMLMapper erzeugt. Funktioniert soweit wie erwartet, aber leider nicht, wenn Umlaute ins Spiel kommen. Ich habe einiges ausprobiert, aber noch keine Möglichkeit gefunden, die fehlerhafte Anzeige in den TDBEdit Komponenten zu beseitigen. Es werden die Umlaute (manchmal erst beim zweiten Laden!) korrekt dargestellt. Wenn nicht, werden die UTF8-Entsprechungen angezeigt also zum Beispiel statt "äää" im XML wird "äää" angezeigt. Wenn man in dieses Feld klickt wird daraus unmittelbar "äää". Nachdem der Fokus dieses Feld verlässt, wird dort "���" angezeigt. Die Werte werden aber korrekt in die Datenbank übernommen. Allerdings nur in diesem Feld. Alle anderen, die Umlaute enthalten werden falsch kodiert zurückgeschrieben. Bin mir noch nicht sicher, wo genau die Konvertierung bzw. der Fehler stattfindet. Vielleicht sind es die visuellen Komponenten. Die automatisch erzeugten Felder für das ClientDataSet sind vom Typ TStringField. Diese Klasse hat ein Feld Value, welches vom Typ AnsiString ist. Für Hilfe wäre ich sehr dankbar. |
AW: ClientDataSet mit XML und UTF8
Hm, wie wäre es mit debuggen? Und wenn das nicht hilft loggen?
|
AW: ClientDataSet mit XML und UTF8
Hallo,
die letzten beiden Sätze enthalten doch schon die Ursache. Also hat die automatische Ermittlung der Feldtypen nicht ganz geklappt. AnsiString ist definitiv falsch -> Ändern |
AW: ClientDataSet mit XML und UTF8
Danke schon mal für die Beiträge.
Ganz so einfach ist es leider nicht. Wenn einfach nur die Datentypen falsch wären, müsste es zu einer konsistent falschen Anzeige kommen. Das ist aber nicht der Fall. Debugging ist auch nicht ganz so trivial, da es schon recht tief in die VCL geht und ich vieles nicht mehr verstehe. Ich hatte gehofft, dass dieses vielleicht vor mit jemand gelöst hätte. Manchmal sind ja nur Kleinigkeiten, die man übersieht. Schliesslich werkerln da einige Komponenten zusammen.... |
AW: ClientDataSet mit XML und UTF8
Am Einfachsten von UTF8 noch ASCII konvertieren oder nach UCS-2 (WideString)
|
AW: ClientDataSet mit XML und UTF8
UTF8 To Ansi geht ja auch, aber eben nicht zusammen mit diesen Komponenten. An keiner vernünftigen Stelle kann man da eingreifen.
Interessanterweise werden nicht mal die Methoden "OnGetText" und "OnSetText" der DatenbankObjekte dann aufgerufen, wenn man meint, dass sie aufgerufen werden müssten. So wie ich das sehen, werden die nur ein einziges Mal aufgerufen, was ich nicht verstehe. Ich habe mich schon einige Stunden damit auseinandergesetzt und eine "einfache" Lösung, d.h. eine Konvertierung irgendwo geht eben genau nicht. Vielleicht stelle ich mal ein einfaches Beispiel so zusammen, dass ich den Code hier posten kann. PS: ich habe das gerade mal unter XE 10.2.1 Tokyo getestet - identisches Verhalten |
AW: ClientDataSet mit XML und UTF8
Liste der Anhänge anzeigen (Anzahl: 1)
So, damit es sicher jeder, der möchte, ansehen kann, habe ich ein kleines Testprojekt mit dem beschriebenen Problem hochgeladen.
Darin werden erstmal keine Konvertierungen automatisch vorgenommen, also verhält es sich unverändert. |
AW: ClientDataSet mit XML und UTF8
Kann das Projekt mit einer Professional Version oder nur mit einer der "größeren" Delphi-Editionen getestet werden? (ich nehme an, das die XTR Unterstützung in Professional nicht enthalten ist, Tester müssten daher eine Edition > Professional besitzen)
|
AW: ClientDataSet mit XML und UTF8
Zitat:
|
AW: ClientDataSet mit XML und UTF8
Das Projekt wurde unter XE3 Professional bearbeitet und gespeichert. Inwieweit andere Versionen damit umgehen können, weiß ich aktuell nicht. Die aktuellste Demo (ist immer wohl die höchste Version), kann es öffnen.
Dank & Gruß |
AW: ClientDataSet mit XML und UTF8
Liste der Anhänge anzeigen (Anzahl: 1)
Was soll dieses
Delphi-Quellcode:
bringen (außer dass sich der Compiler zurecht darüber beschwert)? Da ist weit und breit kein UTF-8 in dem Programm, du verwendest ausschließlich WideStrings und UTF-8 kommt standardmäßig in Delphi-Anwendungen überhaupt nicht vor. Das ergibt doch überhaupt keinen Sinn und ohne das funktioniert das Programm dann auch vernünftig. Zumindest unter D2009. Das entsprechende Kompilat ist angehängt. Einzige Änderung ist das Entfernen von UTF8ToString in der einen Zeile und das Entfernen von Namespaces, da D2009 so gut wie keine Namespaces kennt.
UTF8ToString
/Edit: Ups, falscher Anhang (war das fehlerhafte Programm). |
AW: ClientDataSet mit XML und UTF8
Liste der Anhänge anzeigen (Anzahl: 1)
Naja, im Programm kommt es nicht vor, aber in der XML-Datei, die zu importieren ist.
BTW, mein Screenshot mit exakt denselben Daten sieht etwas anders aus. Wenn konvertiert wird, ist die Ansicht teilweise korrekt, aber eben nicht immer, siehe oben. |
AW: ClientDataSet mit XML und UTF8
und nochmal: die Zeichenketten, die die Datenelemente des ClientDataSet repräsentieren, sind vom Typ AnsiString. Vielleicht ist das bei D2009 ja anders.
Insofern macht die Konvertierung von UTF8 nach Ansi sehr wohl Sinn. UTF8ToString wird ja beim Laden nicht benutzt. Einzig dann, wenn über den Button2 eine Knovertierung versucht werden soll. Wie man am Screenshot erkennen kann, klappt selbst das unkonvertierte Einlesen überhaupt nicht. Dein Erfolgsfall wird wohl an der Delphi Version liegen. |
AW: ClientDataSet mit XML und UTF8
@Redeemer:
Bitte schau doch mal nach, welchen Typ die ClientDataSet Datenelemente haben, also zum Beispiel "ClientDataSet1company". Dieses ist hier vom Typ TStringField, welches die Eigenschaft Value vom Typ AnsiString hat. Wenn es bei D2009 als WideString definiert ist, könnte ich die VCL eventuell anpassen. Wobei das ziemlich umständlich werden könnte, weil da etliche Dateien von abhängen, die im Interface als Antwort AnsiString erwarten. |
AW: ClientDataSet mit XML und UTF8
Das ist auch in D2009 ein AnsiString. Daher können Nicht-Ansi-Zeichen auch nicht angezeigt werden. Die vorliegende XML-Datei enthält nur ANSI-Zeichen.
Ist ja schön, dass die XML in UTF-8 ist, aber das Programm hat mit der XML-Datei doch überhaupt nichts am Hut. Das wird irgendwie vom XMLTransformProvider1 gehandelt, wie interessiert einen nicht. Du solltest eher mal schauen, wie man das Teil dazu kriegt, UTF-8 zu unterstützen. In Delphi 2009 funktioniert das sofort. Da die entsprechenden Komponenten aber nicht Unicode-fähig sind, kannst du natürlich auch die XML in ANSI abspeichern... |
AW: ClientDataSet mit XML und UTF8
Hm, das sehe ich etwas anders.
Die beiliegende XML-Datei ist keine ANSI-Datei! Einfach mal mit einem HEX-Editor öffnen, schon sieht man, dass die Umlaute mit 16 Bit kodiert sind. Ganz simples UTF8. Der Fehler liegt vermutlich in der Umsetzung des ganzen Unicode-Getöses. In der Datei DB.data.pas habe ich an einer Stelle gefunden (getter/setter Methoden), dass explizit TEncoder.ANSI benutzt wird. Das habe ich mal testweise auf UTF8 umgestellt, schon klappt das Laden einwandfrei. Nur das Speichern noch nicht, wo wahrscheinlich das gleiche Problem nochmal auftritt. Trotz der von mir geänderten Konvertierung dort werden zwar die Bytes des UTF8-Strings erzeugt, aber nicht korrekt in die XML-Datei geschrieben. EDIT die Datei heißt data.db.pas |
AW: ClientDataSet mit XML und UTF8
Aber vielen Dank natürlich für Deine Mithilfe und Vorschläge.
Wenn Du mehrere Delphi-Versionen hast, die zu unterschiedlichen Ergebnissen führen, dann wäre es hilfreich zu sehen, wo die Unterschiede zwischen den Dateien liegen. Also besonders bei der data.db.pas Datei. Bin mir ziemlich sicher, dass es unterschiedliche Interfaces bzw. Konvertierungen zwischen den String-Typen gibt. |
AW: ClientDataSet mit XML und UTF8
Zitat:
Dein Delphi lädt die Datei falsch. Meins lädt sie richtig, auch mit anderen Encodings. Es geht hier nur um das Laden der Datei, das hat mit deinem Programm überhaupt nichts zu tun sondern wird von Delphi erledigt – oder in deinem Fall eben nicht. Aber es ist nicht die Aufgabe deines Programms, die Datei zu dekodieren. Es gibt ein Feld für WideString, aber ich bekomme mein Delphi nicht dazu, das zu unterstützen. Es meint, das Feld sei kein Widestring sondern ein String. Ich verstehe nicht, woran es das festmacht. |
AW: ClientDataSet mit XML und UTF8
Leider ist die Vorgabe, dass die XMl-Dateien als UTF8 kodiert sind, weil diese aus anderen Systemen stammen. Anfangs habe ich mit unterschiedlichen Kodierungen einiges ausprobiert, hat aber nie zum Erfolg geführt. Es war immer das gleiche fehlerhafte Verhalten.
Und ich bin mir relativ sicher, dass es in der Datei db.data.pas liegt. Und was meinst Du mit "erledigt Delphi"? Wer ist Delphi? Das Programm sollte den Code ausführen, den ich programmiere bzw per Komponenten einfüge. Der Fehler liegt in der VCL. Es kann doch nicht angehen, dass das Funktionieren von der Delphi-Version abhängt. Ich sehe in meinen 5 Zeilen Code keinen Fehler, was Du mit der D2009 ja auch bestätigt hast. Leider haben die wieder irgendwo was verschlimmbessert, und das zieht sich bis in neueste Version. Eigentlich ein schlechter Scherz und ein sicheres Zeichen dafür, dass nicht vernünftig getestet wird. Stattdessen Featuritis an allen erdenklichen Stellen. Fehlerfreiheit und Robustheit zählen nicht mehr. Hauptsache mindestens im Jahrestakt neue Versionen raushauen, die wieder neue Fehler beinhalten. Und das bei diesen Preisen... Man stelle sich nur vor, in größeren Projekten sich durch ein Update der IDE so was schönes einzufangen. |
AW: ClientDataSet mit XML und UTF8
Ja, ich meine mit "erledigt Delphi" eigentlich "erledigt die VCL".
An deinem Code ist einfach falsch, dass du die Eingabe des Nutzers vor dem Speicher noch konvertierst. Das ist eben auch nicht dein Job, zumindest an dieser Stelle. Ich habe in meiner DB.pas von D2009 keine Referenz auf irgendein Encoding gefunden. |
AW: ClientDataSet mit XML und UTF8
Ich konvertiere aber in meinem Beispielprogramm gar nicht. Deshalb, und auch weil es unter D2009 offensichtlich fehlerfrei läuft, mache ich in meinem Code auch keinen Fehler. Der Fehler liegt eindeutig in der VCL in neueren Versionen.
Wen die Lösung und die entsprechend notwendige Änderung interessiert, kann es hier nachlesen. Gilt für alle Versionen die neuer sind als D2010. ![]() Wieder mal sehr schön, dass offensichtliche Fehler in neuere Versionen reinprogrammiert werden, ohne dass es entsprechende Korrekturen gibt. Stattdessen immer neue Versionen mit neuen Fehlern zu höheren Preisen. Glaube nicht, dass das noch lange gut geht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz