Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi TXMLDocument und Umlaute (https://www.delphipraxis.net/136812-txmldocument-und-umlaute.html)

mjustin 8. Jul 2009 11:18


TXMLDocument und Umlaute
 
Hallo,

In Delphi 2009 habe ich eine Fehlermeldung bei der Verwendung von TXMLDocument mit Umlauten. Beim Zurücklesen der XML Datei wird die Fehlermeldung ''An invalid character was found in text content.' angezeigt, beim Setzen von Active auf True. Im Editor wird UTF-8 Codierung verwendet.

In Notepad und Wordpad sieht die Datei gut aus:

<?xml version="1.0"?>
<a>äöü</a>

In XmlSpy wird ein Quadrat statt den Umlauten angezeigt.

Ist das ein bekanntes Problem?

Delphi-Quellcode:
procedure TfrmMain.Button1Click(Sender: TObject);
var
  xmlDoc: IXMLDocument;
  N: IXmlNode;
begin
  xmlDoc := TxmlDocument.Create(nil);
  xmlDoc.Active := True;
  xmlDoc.Encoding := 'UTF-8';
  N := xmlDoc.AddChild('a');
  N.Text := 'äöü';
  with TStringlist.Create do
  try
    Text := xmlDoc.XML.Text;
    SaveToFile('test.xml');
  finally
    Free;
  end;
end;

procedure TfrmMain.Button2Click(Sender: TObject);
var
  xmlDoc: IXMLDocument;
  N: IXmlNode;
begin
  xmlDoc := TxmlDocument.Create(nil);
  xmlDoc.XML.LoadFromFile('test.xml');
  xmlDoc.Active := True;               <---- Exception
  N := xmlDoc.DocumentElement;
  ShowMessage(N.Text);
end;

himitsu 8. Jul 2009 11:24

Re: TXMLDocument und Umlaute
 
in dem XML-Header <?xml version="1.0"?> fehlt die Codierung und ist das äöü als Ansi oder UTF-8 in der Datei (ich vermute mal kein UTF-8, da MSXML TStringlist per Standard keinen BOM speichert und ohne UTF8-Kennung hätte der Editor die Zeichen ja wohl nicht decodiert)

und wenn die Zeichen als Ansi in der Dateistehen und XML per Standard (ohne Codierungsangabe) UTF-8 Codiert ist, dann entsprechen die Byte-Codes von äöü keinem UTF-8-Zeichen, also die Fehlermeldung wäre korrekt

[add]
aber warum gehst du über die StringList? :gruebel:
Delphi-Quellcode:
var
  xmlDoc: IXMLDocument;
  N: IXmlNode;
begin
  xmlDoc := TxmlDocument.Create(nil);
  xmlDoc.Active := True;
  xmlDoc.Encoding := 'UTF-8';
  N := xmlDoc.AddChild('a');
  N.Text := 'äöü';
  xmlDoc.XML.('test.xml');
end;
oder gib dem SaveToFile der TStringList die Codierung mit, also sag TStringList expliziet, daß es als UTF-8 Speichern soll

mjustin 8. Jul 2009 11:34

Re: TXMLDocument und Umlaute
 
Zitat:

Zitat von himitsu
in dem XML-Header <?xml version="1.0"?> fehlt die Codierung und ist das äöü als Ansi oder UTF-8 in der Datei (ich vermute mal kein UTF-8, da MSXML keinen BOM speichert und ohne UTF8-Kennung hätte der Editor die Zeichen ja wohl nicht decodiert)

und wenn die Zeichen als Ansi in der Dateistehen und XML per Standard (ohne Codierungsangabe) UTF-8 Codiert ist, dann entsprechen die Byte-Codes von äöü keinem UTF-8-Zeichen, also die Fehlermeldung wäre korrekt

Im Editor wird die UTF-8 Codierung verwendet. IXMLNode.Text ist vom Typ string, hier sollte der Compiler daher eigentlich den Text automagisch nach UnicodeString konvertieren. Ich schaue mal was es noch an Möglichkeiten gibt.

himitsu 8. Jul 2009 11:41

Re: TXMLDocument und Umlaute
 
Das ist aber dem XML-Parser egal, ohne Kodierungsinformation (im Prozessortag <?xml ?> ) wird erstmal von UTF-8 ausgegangen, wobei MSXML netter Weise auch noch die BOM beachtet, aber einwas von Beidem muß angegeben sein.

Die XML-Spec besagt halt, wenn nichts angegeben ist, dann ist es UTF-8.

Und selbst wenn IXMLNode.Text vom Typ String ist, die TStringList in D2009 speichert doch per Standard erstmal alles nur als ANSI ab (glaub ich :gruebel: ) , wegen der Kompatibilität zu älteren Textdateien bzw. älteren Programmen.

mjustin 8. Jul 2009 11:45

Re: TXMLDocument und Umlaute
 
Zitat:

Zitat von himitsu

oder gib dem SaveToFile der TStringList die Codierung mit, also sag TStringList expliziet, daß es als UTF-8 Speichern soll

Das hilft, danke! Es wundert den Laien natürlich, dass man das Encoding noch mal angeben muss - aber mit Delphi 2009 wird ja aus dem Stringlist-Text ein UnicodeString. Und der weiss natürlich nichts vom Encoding des dahinterstehenden XML Dokuments.

Tests mit kyrillischem Encoding des Dokuments in Kombination mit TEncoding.<irgendwas exotisches> beim SaveToFile kommen dann später :)

Der minimale Code ist dann:

Delphi-Quellcode:
procedure TfrmMain.Button1Click(Sender: TObject);
var
  xmlDoc: IXMLDocument;
  N: IXmlNode;
begin
  xmlDoc := TxmlDocument.Create(nil);
  xmlDoc.Active := True;
  N := xmlDoc.AddChild('a');
  N.Text := 'äöü';
  // xmlDoc.XML.SaveToFile('test.xml', TEncoding.UTF8);
  // noch kürzer:
  xmlDoc.SaveToFile('test.xml');
end;

himitsu 8. Jul 2009 12:07

Re: TXMLDocument und Umlaute
 
Eigentlich dachte ich xmlDoc.SaveToFile('test.xml'); nimmt die Kodierung, welche unter xmlDoc.Encoding angegeben ist :shock: ... hat MSXML zumindestens in meinen Tests so gemacht (siehe himXML die CheckLibs-Demo, da sind auch MSXML, OmniXML und Co. drin)

mjustin 8. Jul 2009 12:29

Re: TXMLDocument und Umlaute
 
Zitat:

Zitat von himitsu
Eigentlich dachte ich xmlDoc.SaveToFile('test.xml'); nimmt die Kodierung, welche unter xmlDoc.Encoding angegeben ist :shock: ... hat MSXML zumindestens in meinen Tests so gemacht (siehe himXML die CheckLibs-Demo, da sind auch MSXML, OmnyXML und Co. drin)

Stimmt, ich meinte auch xmlDoc.SaveToFile('test.xml') und habe das Coebeispiel korrigiert, sorry!


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