Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TidHTTP.Get um TXMLDocument zu füllen (https://www.delphipraxis.net/146106-tidhttp-get-um-txmldocument-zu-fuellen.html)

Sherlock 13. Jan 2010 15:35


TidHTTP.Get um TXMLDocument zu füllen
 
Ich versuche was eigentlich ganz simples...dachte ich.
Ich möchte das XML, das hinter diesem Link steckt http://www.google.com/ig/api?weather...+Germany&hl=de auslesen und dann parsen. Dazu habe ich mittlerweile drei verschiedene GETs ausprobiert, die alle das gleiche Problem liefern, leider habe ich nicht so viele XMLDocument-Typen zur Auswahl. Was ist das Problem?
Delphi-Quellcode:
var
XMLDoc :TXMLDocument;
IdHPP1 : TIdHTTP;
.
.
.
  XMLDoc.XML.Text := IdHTTP1.Get(Trim(edURL.Text));
  XMLDoc.Active := True;
Das XML wird definitv eingelesen, allerdings kommen immer wieder Fehler beim Parsen.
Und zwar EDOMParseError (An invalid character was found in text content).

Zwischenzeitlich bin ich etwas tiefer ins XML gekommen da kam der EConvertError (den bekomme ich allerdings nicht mehr seit ich mit dem Indy versuche einzulesen) und zwar zum Beispiel bei Umlauten oder auch beim Prozentzeichen der Luftfeuchtigkeit.

Encoding ist UTF-8.

Weiss jemand Rat?

Edit: Ich habe auch probiert über Streams zu gehen (XMLDoc.XML.LoadFromStream), das liefert die gleichen Probleme.

Sherlock

nahpets 13. Jan 2010 16:06

Re: TidHTTP.Get um TXMLDocument zu füllen
 
Hallo,

das Einzige, was mir aufgefallen ist:

Das Leerzeichen vor dem Prozent ist kein "gewöhnliches" Blank (Hex 20) sondern "irgendwas" Anderes (Hex A0).
Liegt da eventuell ein Problem. Der IE kann die XML-Seite problemlos einlesen, so dass ich mal von einem korrekten XML ausgehe.

Schreib' doch die mit get geholte Seite erstmal ins Dateisystem und lass' sie Dir vom IE anzeigen (oder einem anderen Tool zum Anzeigen von XML - XMLSpy oder...)

Umlaute... kommen in der Seite ja nicht vor, so dass der Fehler für mich momentan nicht nachvollziehbar ist.
Muss irgendein "exotisches" Problem sein :-(.

Sherlock 13. Jan 2010 16:21

Re: TidHTTP.Get um TXMLDocument zu füllen
 
Ah, das Leerzeichen, das ist ein guter Hinweis. Umlaute...nunja, je nach WEtterlage kanns auch mal "Bewölkt" sein.

Ich probier das mit dem Speichern morgen früh direkt mal aus. Vielen Dank für den Tipp. Schönen Feierabend.

Sherlock

himitsu 13. Jan 2010 16:34

Re: TidHTTP.Get um TXMLDocument zu füllen
 
Zitat:

Zitat von nahpets
Der IE kann die XML-Seite problemlos einlesen, so dass ich mal von einem korrekten XML ausgehe.

Der IE ist kein XML Parser.
Da viele HTML-Seiten total mit Fehlern gefüllt sind, arbeiten HTML-Parser fehlerresistent und versuchen vieles "irgendwie" dennoch auszuwerten und anzuzeigen.

XML-Parser arbeiten da strickter ... was eigentlich nicht schlimm ist, da XML "streng" geregelte Regeln/Spezifikationen besitzt.

$A0 ist
Delphi-Quellcode:
kein
UTF-8-Zeichen, also wird der Fehler korrekt angezeigt.


Die genannte XML-Datei ( http://www.google.com/ig/api?weather...+Germany&hl=de ) besitzt keinen XML-Header und ohne sollte es laut XML-Spec UTF-8 sein, aber hier sieht es mehr nach ANSI aus.

Lösung: entweder nach UTF-8 konvertieren, bevor du es an TXMLDocument übergibst
oder du setzt einen XML-Header (XMLInstructionNode) davor, welcher was von ANSI sagt.



PS: Geh über den Stream, denn sonst bekommst du ab D2009 Probleme.
aktuell (bis D2007) könnte man es so versuchen
Delphi-Quellcode:
XMLDoc.XML.Text := '<?xml version="1.0" encoding="ISO-8859-1"?>' + IdHTTP1.Get(Trim(edURL.Text));
aber besser kommst du, du downloadest die Datei in einen Stream,
fügst vor den Dateidaten das '<?xml version="1.0" encoding="ISO-8859-1"?>' ein (natürlich als ANSI)
und nutzt dann LoadFromStream.

PSS: genau wegen sowas kann man bei himXML auch einen "Default"-Kodierung angeben ... also wenn die "angegebene" Kodierung nicht mit der tatsächlichen Kodierung übereinstimmt.

nahpets 13. Jan 2010 16:53

Re: TidHTTP.Get um TXMLDocument zu füllen
 
Hallo,
Zitat:

Zitat von himitsu
Zitat:

Zitat von nahpets
Der IE kann die XML-Seite problemlos einlesen, so dass ich mal von einem korrekten XML ausgehe.

Der IE ist kein XML Parser.
Da viele HTML-Seiten total mit Fehlern gefüllt sind, arbeiten HTML-Parser fehlerresistent und versuchen vieles "irgendwie" dennoch auszuwerten und anzuzeigen.

XML-Parser arbeiten da strickter ... was eigentlich nicht schlimm ist, da XML "streng" geregelte Regeln/Spezifikationen besitzt.

$A0 ist
Delphi-Quellcode:
kein
UTF-8-Zeichen, also wird der Fehler korrekt angezeigt.


Die genannte XML-Datei ( http://www.google.com/ig/api?weather...+Germany&hl=de ) besitzt keinen XML-Header und ohne sollte es laut XML-Spec UTF-8 sein, aber hier sieht es mehr nach ANSI aus.

Lösung: entweder nach UTF-8 konvertieren, bevor du es an TXMLDocument übergibst
oder du setzt einen XML-Header (XMLInstructionNode) davor, welcher was von ANSI sagt.



PS: Geh über den Stream, denn sonst bekommst du ab D2009 Probleme.
aktuell (bis D2007) könnte man es so versuchen
Delphi-Quellcode:
XMLDoc.XML.Text := '<?xml version="1.0" encoding="ISO-8859-1"?>' + IdHTTP1.Get(Trim(edURL.Text));
aber besser kommst du, du downloadest die Datei in einen Stream,
fügst vor den Dateidaten das '<?xml version="1.0" encoding="ISO-8859-1"?>' ein (natürlich als ANSI)
und nutzt dann LoadFromStream.

PSS: genau wegen sowas kann man bei himXML auch einen "Default"-Kodierung angeben ... also wenn die "angegebene" Kodierung nicht mit der tatsächlichen Kodierung übereinstimmt.

Stimmt, der IE selbst ist kein Parser, er benutzt den von Microsoft.
Bisher hat er mir noch keine XML-Datei angezeigt, die einen Fehler enthielt. Bei XML geht er anders vor als bei HTML, bei HTML darf geschludert werden, bei XML nicht.

Die Datei von Google enthält am Anfang die 3 typischen Bytes für UTF-8-Dateien, auch wenn es nicht nochmal explizit woanders steht. Das mag auch ein Problem sein. Ultraedit erkennt die Datei jedenfalls als UTF-8, zumindest dann, wenn man beim IE sagt: "Quelltext anzeigen". Will' nicht ausschließen, dass es erst dann UTF-8 wird.

Nagut: Wenn man die Datei per Indy holt, ist es ganz eindeutig kein UTF-8, aber die Hex A0 vor dem Prozentzeichen bleibt.

himitsu 13. Jan 2010 17:03

Re: TidHTTP.Get um TXMLDocument zu füllen
 
Ahhrg, hatte mir die Datei jetzt nur mal kurz im FF angesehn.
- in der Anzeige fehlt <?xml ...?> und ein BOM wird dort natürlich auch nicht angezeigt
- und bei "Quelltext anzeigen" bekommt man eine veränderte Datei zu sehn
- nach "Datei speichern unter" bekommt man eine Datei mit einem nochmal ganz anderem Inhalt :shock:

OK, laut Spec ist ein BOM erlaubt,
aber es bleibt dabei A0 gehört nicht in UTF8 rein.

Habt ihr mal mitbekommen, wie/ob dort Umlaute kodiert sind?

nahpets 13. Jan 2010 17:08

Re: TidHTTP.Get um TXMLDocument zu füllen
 
Hallo,

wenn ich die Datei direkt mit Indy hole (ohne irgendeinen Browser...) bekomme ich kein UTF-8 sondern ANSI (1 Byte pro Zeichen). Die A0 ist da aber auch drin enthalten.

himitsu 13. Jan 2010 17:14

Re: TidHTTP.Get um TXMLDocument zu füllen
 
Zitat:

Zitat von nahpets
wenn ich die Datei direkt mit Indy hole (ohne irgendeinen Browser...) bekomme ich kein UTF-8 sondern ANSI (1 Byte pro Zeichen). Die A0 ist da aber auch drin enthalten.

Wenn eine Datei kein BOM und auch keine Kodierung ( <?xml encoding="..." ?> ) enthält, dann wird es standardmäßig als UTF-8 angesehn ... so schreiben es die XML-Spezifikationen vor.

Und demnach ist die A0 ein ungültiges Zeichen.

Darum auch meine Frage,
Zitat:

Habt ihr mal mitbekommen, wie/ob dort Umlaute kodiert sind?
denn so wie es aussieht, könnte es ein Implementierungsfehler seitens Google sein.
lade mal bitte Berlin runter http://www.google.de/ig/api?weather=Berlin - dort ist grad ein ö drinnen

ps: himXML kann ungültige Zeichen "ignorieren" (xoChangeInvalidChars ist standardmäßig sogar schon gesetzt und wandelt alles Ungültige in ein Leerzeichen um)

Wie gesagt, wenn kein BOM und kein <?xml ?> enthalten ist, dann setze einfach ein entsprechendes <?xml ...?> für einen ANSI-Kodierung davor.

Sherlock 14. Jan 2010 09:47

Re: TidHTTP.Get um TXMLDocument zu füllen
 
OK, funktioniert, wenn ich noch vorher das
XML-Code:
 <?xml version="1.0"?>
aus dem Google entferne.
Jetzt komm ich weiter, vielen Dank!

:dp:

Sherlock


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