Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten (https://www.delphipraxis.net/116441-msxml-mit-unicode-mit-hilfe-der-msxml2_tlb-bearbeiten.html)

F.W. 29. Jun 2008 14:02


MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Hi Leutz!

Ich schreibe gerade meine erste Anwendung, die richtig mit Unicode umgehen können soll. Und zwar sollen Unicode- (also Wide-) Strings in eine XML Datei geschrieben werden.
Soweit ich weiß, sollte das kein Problem sein. Ich habe auch schon das Encoding gesetzt (was auch ok sein sollte):
XML-Code:
<?xml version="1.0" encoding="UTF-16"?><head/>
Das ganze wird über xmlDoc.loadXML() (xmlDoc: IXMLDOMDocument2) geladen.
Meine Frage ist nun:
Kann ich einfach so im Delphiquellcode geschriebene Bezeichner (die ja nicht Unicode sind) ohne Typcasting benutzen oder muss ich immer vorher StringToWideChar nehmen und das an z.B. setAttribute() übergeben?
Und gibt es eine Möglichkeit festzustellen, ob ein WideString verlustfrei in einen normalen String zu konvertieren geht?

sx2008 29. Jun 2008 14:39

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Zitat:

Zitat von F.W.
Kann ich einfach so im Delphiquellcode geschriebene Bezeichner (die ja nicht Unicode sind) ohne Typcasting benutzen ... übergeben?

Ja, eine Umwandlung von String (AnsiString) nach WideString geht immer verlustlos.
Zitat:

Zitat von F.W.
Und gibt es eine Möglichkeit festzustellen, ob ein WideString verlustfrei in einen normalen String zu konvertieren geht?

Delphi-Quellcode:
var
  a, c : Widestring;
  b : AnsiString;
begin
  // ungetestet, aber mit dem Symbol müsste die Umwandlung fehlschlagen, ohne geht alles glatt
  a := 'Das Möbel müffelt mächtig '+#$2801; // #$2801 müsste ein Braille-Symbol sein
  b := a;
  c := b;
  if a <> c then ShowMessage('Problem bei Umwandlung');

F.W. 29. Jun 2008 14:58

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Zitat:

Ja, eine Umwandlung von String (AnsiString) nach WideString geht immer verlustlos.
Gut, da kann ich mir die Arbeit schonmal sparen :-)

Zum zweiten Problem:
Der Quellcode funktioniert leider nicht. Ich habs mal mit Haltepunkten mir angesehen:
Delphi wandelt das ungültige Zeichen in ein '?' um, bei beiden Strings und somit merkt es nicht, dass es da was eingebüßt hat.

F.W. 29. Jun 2008 15:12

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Ok, ich hab jetzt was gefunden! Nach längerem Rumprobieren hab ich mir überlegt, dass ich ja nicht WideString und AnsiString vergleichen muss, sondern den AnsiString ja wieder zurückkonvertieren kann und dann WideString und WideString vergleichen kann. (der direkte Vergleich zwischen WideString und AnsiString ging nicht, oder ich hab was falsch gemacht).
So habe ich jetzt jedenfalls folgenden Code, der mit dem Beispielstring von sx2008 geklappt hat:
Delphi-Quellcode:
var
 W : Widestring;
 S : String;
 PW: PWideChar;
begin
 W := 'Das Möbel müffelt mächtig '+#$2801;

 S := WideCharToString(@W[1]);
 GetMem(PW, Length(S)*2+1);
 StringToWideChar(S, PW, Length(S)*2+1);
 if W <> PW then ShowMessage('Problem bei Umwandlung');
 FreeMem(PW);
end;
Was ich nur gern nochmal von jemandem bestätigt hätte ist, dass ich für einen PWideChar GetMem(PW, Length(AnsiString)*2+1) aufrufen muss.?
Irgendwie zieht es mich bei WideStrings immer dazu GetMem(...,...+2) zu reservieren...

sx2008 29. Jun 2008 15:12

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Zitat:

Zitat von F.W.
Der Quellcode funktioniert leider nicht. Ich habs mal mit Haltepunkten mir angesehen:
Delphi wandelt das ungültige Zeichen in ein '?' um, bei beiden Strings und somit merkt es nicht, dass es da was eingebüßt hat.

Naja die IDE selber ist nicht Unicode-fähig. Also wandelt der Debugger alle Widestrings -> Ansistrings um, bevor er sie anzeigt.
Versuch mal das:
Delphi-Quellcode:
  a := 'Das Möbel müffelt mächtig ';
  a := a + #$2801; // und jetzt noch ein Unicodezeichen oberhalb #255 dranhängen
  b := a;
  c := b;
  if a <> c then ShowMessage('Problem bei Umwandlung');
oder vielleicht auch so:
Delphi-Quellcode:
  a := WideString('Das Möbel müffelt mächtig ') + #$2801;

himitsu 29. Jun 2008 15:20

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
wo wandelt es das in ein "?" um?
schon beantwortet

wozu UTF-16? da könnte man als Codierung auch gleich ISO-10646-UCS-2 als Codierung verwenden, hätte direkt Unicode (die das normale 2-Byte-Version) und würde eventuell ein paar Byte einsparen :stupid:

wie wär's mit UTF-8?
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

F.W. 29. Jun 2008 15:26

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Da muss ich jetzt mal gestehen, dass ich nicht so recht weiß, was sich hinter UFT... und ISO... verbirgt.
Ich hab nur bei ner schnellen Suche mit Google UTF-16 als Unicodekompatibel gesehen und das eben genommen.
Wollte dieses Problemchen nicht meine ganze Arbeit aufhalten lassen und habs daher einfach genommen.

Kann mir jemand den Unterschied erklären? Ich weiß eben auch noch nicht (hab noch nicht eine XML damit erzeugen lassen) wie die XML dann aussehen wird. Aber ich will auf alle Fälle gerüstet sein, sollte mal ein Wert, der in der xml gespeichert werden soll, Unicode sein.

Kann mir also jemand erklären was der Unterschied zwischen den ganzen Encodings ist? Oder ne Seite wos gut erklärt ist? Entweder hab ich mich schlecht ausgedrückt oder... hab jedenfalls bei meinen Googlesuchen nichts gefunden.

EDIT: Hab noch schnell die 2. Variante von sx2008 getestet, die geht. Kann man jetzt sagen, ob eine besser ist?
(Vielleicht noch erwähnenswert: Ich arbeite in einer Dll und die bekommt PWideChar übergeben, damit auch andere Programmiersprachen die Dll benutzen können))
Delphi-Quellcode:
var
W : Widestring;
S : String;
PW: PWideChar;
begin
W := 'Das Möbel müffelt mächtig '+#$2801;

S := WideCharToString(@W[1]);
GetMem(PW, Length(S)*2+1);
StringToWideChar(S, PW, Length(S)*2+1);
if W <> PW then ShowMessage('Problem bei Umwandlung');
FreeMem(PW);
end;
oder
Delphi-Quellcode:
var
  a, c : Widestring;
  b : AnsiString;
begin
  a := 'Das Möbel müffelt mächtig ';
  a := a + #$2801; // und jetzt noch ein Unicodezeichen oberhalb #255 dranhängen
  b := a;
  c := b;
  if a <> c then ShowMessage('Problem bei Umwandlung');

himitsu 29. Jun 2008 15:48

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Delphi-Quellcode:
if W <> PW then
vergleicht nur die Pointer (den Zeiger auf die Stringdaten) und nicht die Stringdaten selber.
diese Zeiger sollten auch immer unterschiedlich sein.

http://de.wikipedia.org/wiki/Utf-8

UTF-8 ist sozusagen eine dynamische MultiByte-Codierung, welche auf "ANSI" aufbaut (1 Byte pro Zeichen in der Codierung)

UTF-16 verwendet in der Codierung Unicode (2 Byte pro Zeichen) und ist eher sinnvoll, wenn man in einem 2-Byte-UnicodeString (vom Type her) mehr drinhaben will, also z.B. 4-Byte-Unicodedaten

UCS2 = 2-byte-UniCodeString

F.W. 29. Jun 2008 15:55

Re: MSXML mit Unicode mit Hilfe der MSXML2_TLB bearbeiten
 
Zitat:

Zitat von himitsu
Delphi-Quellcode:
if W <> PW then
vergleicht nur die Pointer (den Zeiger auf die Stringdaten) und nicht die Stringdaten selber.
diese Zeiger sollten auch immer unterschiedlich sein.

Also bei mir hat das aber geklapp (jeweils erwartetes Ergebnis erhalten, für die Strings die ich übergeben habe, also mit und ohne unicode)
Aber rein von der Logik her stimmt schon...
Also werde ichs über sx2008's Code machen... ;-)


Ich hab Encoding jetzt auf UTF-8 gestellt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:34 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