vorweg - ich bin noch nicht so fit, was Object-Pascal angeht.
Zu meiner Problembeschreibung: Ich lade mir von http://www.ecb.europa.eu/stats/eurofxre ... f-hist.xml" onclick="window.open(this.href);return false; die kompletten Euro-Wechselkurse in einen MemoryStream und verwende zum Parsen des so erhaltenen XML-Dokuments die TALXmlDocument-Komponente von Alcinoe, was recht bequem zu realisieren ist. Leider musste ich dabei feststellen, dass bei eben diesem grossen Dokument (~3mb) nicht der komplette Inhalt bearbeitet wird, sondern bei ca. 14000 bearbeiteten Elementen Schluss ist - dummerweise auch noch ohne Fehlermeldung. Der Download ist komplett (habe den MemoryStream in eine Textdatei gespeichert) und die Daten stellen auch gültiges XML dar (ebenso getestet). Hier mal die relevanten Teile des Codes.
Code: Alles auswählen
procedure TMainForm.StartDownloadClick(Sender: TObject);
var
ms: TmemoryStream;
begin
ms := TMemoryStream.Create;
try
// Indy-IdHTTP-Komponente mit URL aus Kombifeld füttern und Download
// im MemoryStream ms ablegen
with UrlSelectCombo do
IdHTTP1.Get(string(Items.Objects[ItemIndex]), ms);
// ms.Position := 0; {hilft leider nicht}
// das Parsen wird sofort eingeleitet, wobei ich eher erwartet hätte
// Active auf True setzen zu müssen oder eine Methode wie parseXML
// aufrufen zu müssen
XMLRates.LoadFromStream(ms);
finally
ms.Free;
end;
end;
procedure TMainForm.XMLRatesParseStartDocument(Sender: TObject);
begin
with Sqlite3Dataset1 do
begin
// Tabelle rates der SQLite3-DB löschen
ExecSQL('delete from rates;');
//SQLList für den Import vorbereiten
SQLList.Clear;
SQLList.Add('begin;');
end;
end;
procedure TMainForm.XMLRatesParseEndDocument(Sender: TObject);
begin
with Sqlite3Dataset1 do
begin
SQLList.Add('commit;');
// SQL-Inserts ausführen
ExecSQLList;
// Daten erneut einlesen
RefetchData;
end;
end;
procedure TMainForm.XMLRatesParseStartElement(Sender: TObject;
const AName: TALXMLString; const Attributes: TStrings);
var
cur: string = ''; // für das Währungskürzel
rate: string = ''; // für den Wechsel-Faktor
sql: string = '';
s: String;
i: integer = 0;
begin
// wird ein Cube Element geparst?
if AName = 'Cube' then
begin
with Attributes do
begin
// enthält es ein Attribute time?
i := IndexOfName('time');
if i = 0 then
begin
// Zeitwert als string ablegen - Format: YYYY-MM-DD
FTime := ValueFromIndex[i];
Exit;
end;
// ist ein currency Attribut vorhanden
i := IndexOfName('currency');
if i >= 0 then
begin
// dann den Wert festhalten
cur := ValueFromIndex[i];
i := IndexOfName('rate');
if i >= 0 then
// ... und den Faktor rate auslesen - (Punkt ist Dezimaltrennzeichen)
begin
rate := ValueFromIndex[i];
// string FTime in Datum konvertieren und dieses als String mit
// Punkt als Dezimaltrennzeichen in s ablegen
Str(ScanDateTime('YYYY-MM-DD', FTime), s);
// SQL-Anweisung erzeugen
sql := 'insert into rates(time,cur,rate) values(%s,''%s'',%s);';
// ... mit Werten bestücken
sql := Format(sql, [s, cur, rate]);
// und der SQLList hinzufügen
Sqlite3Dataset1.SQLList.Add(sql);
end;
end;
end;
end;
end;
schöne Grüsse aus Berlin
Nouba