Einlesen eines XML-Documents aus dem Internet?
spacer
Autor Nachricht
Schosch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: Sa 04.02.12 15:12 
Also Ich arbeite gerade an einem Programm, welches in der Lage sein soll 10 Beträge verschiedener Währungen in einem einzigen Eurowert auszugeben. Die wechselkurse sollen aus dem Internet aktuallisiert werden. Hierfür verwende ich folgende API:

www.ecb.europa.eu/st.../eurofxref-daily.xml

Diese Api ist ein XML-Document, und jetzt versuche ich halt auf die 10 entsprechenden Knotenpunkte dieses Documents zuzugreifen. Hier ist der entsprechende Ausschnitt aus meinem Quellcode:


ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
uses
...IdHTTP, DOM, XMLRead, XMLWrite;

procedure TForm1.FormCreate(Sender: TObject);
var PassNode :TDOMNode;
API: TIdHttp;
Doc: TXMLDocument;
begin
Doc:=TXMLDocument.Create;
API:=TIdHTTP.Create;

API.Get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
ReadXMLFile(Doc,API);

// Die Wechselkurse sind erstmal Lokal im Programm, doch hier sollen anstadt die
// Lokalen Werte die entsprechenden Werte aus der API stehen.
Waehrungen[0]:=1.2332; //Australien
Waehrungen[1]:=8.2179; //China
Waehrungen[2]:=1.3129; //Canada
Waehrungen[3]:=7.4358; //Dänemark
Waehrungen[4]:=0.83625; //Groß Britanien
Waehrungen[5]:=65.0780; //Indien
Waehrungen[6]:=100.10; //Japan
Waehrungen[7]:=8.7791; //Schweden
Waehrungen[8]:=1.2061; //Schweiz
Waehrungen[9]:=1.3017; //USA


ind der zeile (ReadXMLFile(Doc,API);) kommt eine Fehlermeldung:

Unit1.pas(722,22) Error: Incompatible type for arg no. 2: Got "TIdHTTP", expected "TStream"

keine Ahnung was die genau bedeutet. Ich vermute mal das ich hier eine Rückgabetyp-Umwandlung vornehmen muss, nur wüsste ich auch nicht wie diese aussieht, da dies mein erstes Projekt im zusammenhang mit dem indernet und einem XML-Documents ist... Also bitte ich hier um Hilfe.

Moderiert von user profile iconNarses: Titel geändert.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.


Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Sa 04.02.12 15:40 
Das hat nichts mit einer Rückgabetyp-Umwandlung zu tun. Denn den Rückgabewert wirfst du ja weg beim Aufruf von Get.

Du versuchst an ReadXMLFile statt den XML-Daten ein IdHttp-Objekt zu übergeben. Das ist wie wenn du zur Passkontrolle statt den Pass vom Mitarbeiter der Passausgabestelle zu holen den Mitarbeiter mitnimmst und bei der Passkontrolle versuchst abzugeben...

Schau dir einmal den zweiten Parameter von Get an. Da kannst du einen TMemoryStream übergeben, damit dort die Daten der Seite reingeschrieben werden. Den Stream kannst du dann wiederum an ReadXMLFile übergeben.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: Sa 04.02.12 17:27 
Achsoo, ich hab das jetzt so versuch:

ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
procedure TForm1.FormCreate(Sender: TObject);
var PassNode :TDOMNode;
API: TIdHttp;
Doc: TXMLDocument;
Internetverbindung: Boolean;

begin
Internetverbindung:=true;
Doc:=TXMLDocument.Create;
API:=TIdHTTP.Create;

try
API.Get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
ReadXMLFile(Doc,'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
except
Internetverbindung:=false;
Showmessage('Keine Internet-verbindung möglich');
end;

if Internetverbindung=true then
begin
PassNode := Doc.DocumentElement.FindNode('USD');
WriteLn(PassNode.NodeValue);
WriteLn(PassNode.FirstChild.NodeValue);
end;
end;

aber hier gibt das programm immer die Showmessage aus..
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Sa 04.02.12 17:48 
user profile iconSchosch hat folgendes geschrieben Zum zitierten Posting springen:
Achsoo, ich hab das jetzt so versuch:
Mach es doch stattdessen wie ich geschrieben habe.
Oder du übergibst den Rückgabewert von Get als zweiten Parameter an ReadXMLFile. Das scheint ja auch zu gehen.

Ohne dass du die absoluten Grundlagen lernst, wirst du aber nicht weit kommen. Im Moment schreibst du irgendetwas irgendwohin ohne zu wissen weshalb... :roll:
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: Sa 04.02.12 18:03 
Also meinst du das so, oder wie??

ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
procedure TForm1.FormCreate(Sender: TObject);
var PassNode :TDOMNode;
API: TIdHttp;
Doc: TXMLDocument;
Internetverbindung: Boolean;

begin
Internetverbindung:=true;
Doc:=TXMLDocument.Create;
API:=TIdHTTP.Create;

try
// API.Get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
ReadXMLFile(Doc,API.Get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'));
except
Internetverbindung:=false;
Showmessage('Keine Internet-verbindung möglich');
end;

if Internetverbindung=true then
begin
PassNode := Doc.DocumentElement.FindNode('USD');
WriteLn(PassNode.NodeValue);
WriteLn(PassNode.FirstChild.NodeValue);
end;
end;



Passiet aber genau dass selbe..
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Sa 04.02.12 18:07 
Dann behandle die Exception einmal richtig und schaue was es überhaupt für eine ist. Zeigt die Lazarus nicht auch an? (wie es halt bei Delphi Standard ist)
ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
try
...
except
on E: Exception do
ShowMessage(E.Message);
end;
Ich habe keine Ahnung wie ReadXMLFile funktioniert und habe auch wenig Lust mich dafür mit Lazarus herumzuärgern. ;-)

// EDIT:
Vermutlich musst du wirklich den Weg über einen TMemoryStream gehen. Der zweite Parameter für ReadXMLFile ist offenbar ein Dateiname um die Daten aus einer Datei zu lesen. Das hättest du in Lazarus aber auch sehen können müssen.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: Sa 04.02.12 20:30 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

Vermutlich musst du wirklich den Weg über einen TMemoryStream gehen. Der zweite Parameter für ReadXMLFile ist offenbar ein Dateiname um die Daten aus einer Datei zu lesen. Das hättest du in Lazarus aber auch sehen können müssen.


ja schon, aber ich hab die Datei ja gar nicht auf meinem PC. Also entwerde ich muss das machen wie ich das schon versucht habe (Direckt die informationen aus der API nehmen) oder ich muss versuchen die Datei auf meinen PC zu bekommen und diese dann einfach bei einem neuaufruf des Programmes anzupassen, und die Informationen dann von der aktualisierten Datei auszulesen. Und Beides sind Wege, die mir noch im duckeln liegen...

Also eigentlich wäre mir die zweite Variante lieber, aber da hab ich nich wirklich viel bis gar nichts zu gefunden. Was würdet ihr denn Vorschlagen welche Methonde ich anwenden soll und wie würde das gehen??
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Sa 04.02.12 20:44 
Erstell einen TMemoryStream und übergib den sowohl an Get als zweiten Parameter als auch an ReadXMLFile und fertig.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: Sa 04.02.12 20:55 
Was genau ist TMemoryStream und wie erstelle ich diesen??
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Sa 04.02.12 21:00 
Mehr Informationen über Klassen und Objekte findest du hier:
www.delphi-treff.de/...n-und-objekte/#c4939
Da findest du auch Beispiele wie du ein Objekt erzeugst. Eigentlich hast du das in deinem Quelltext aber auch schon benutzt...

Und Informationen zu TMemoryStream findest du z.B. in der Dokumentation:
lazarus-ccr.sourcefo...s/tmemorystream.html
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: Sa 04.02.12 23:51 
Achso, jetzt hab ich den TMemoryStrem erstellt. Wie muss ich denn jetzt die API zuweisen, ich habs mit LoadFromStream versucht, aber das will nich klappen

ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm.Create(Sender: TObject);
Var Save: TMemoryStream;
begin
Save:=TMemoryStream.Create;

Save.LoadFromStream('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');

.
.
.
.
end;


aber da meinte der dann:
Unit1.pas(729,101) Error: Incompatible type for arg no. 1: Got "Constant String", expected "TStream"
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: So 05.02.12 09:41 
Mach doch einfach nur was ich geschrieben habe... :roll:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Erstell einen TMemoryStream und übergib den sowohl an Get als zweiten Parameter als auch an ReadXMLFile und fertig.
Wo steht da etwas von LoadFromStream? Nirgends.

Get kannst du als zweiten Parameter einen Stream geben, dann werden die Daten der Internetseite da hineingespeichert.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: So 05.02.12 11:33 
ja versuch ich doch, nur ich hab noch nie mit ner TMemoryStream gearbeitet. Wie muss ich den Parameter denn übegeben, da muss ich dem TMemoryStream doch erstmal einen Stream übergeben, damit ich diesen an Get und ReadXMLFile übegeben kann, oder nich??
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: So 05.02.12 12:17 
user profile iconSchosch hat folgendes geschrieben Zum zitierten Posting springen:
da muss ich dem TMemoryStream doch erstmal einen Stream übergeben
Äh, TMemoryStream ist wie der Name schon sagt schon ein Stream...

Du musst gar nichts weiter machen. Einfach nur den TMemoryStream als Parameter hinschreiben...
ausblenden Delphi-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
procedure TForm1.FormCreate(Sender: TObject);
var
PassNode: TDOMNode;
API: TIdHttp;
Doc: TXMLDocument;
PageContents: TMemoryStream;
begin
Doc := TXMLDocument.Create;
API := TIdHTTP.Create;
try
PageContents := TMemoryStream.Create;
try
try
API.Get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml', PageContents);
PageContents.Position := 0;
ReadXMLFile(Doc, PageContents);
PassNode := Doc.DocumentElement.FindNode('USD');
WriteLn(PassNode.NodeValue);
WriteLn(PassNode.FirstChild.NodeValue);
except
on E: Exception do
Showmessage('Keine Internetverbindung möglich:'#13#10 + E.Message);
end;
finally
PageContents.Free;
end;
finally
API.Free;
end;
end;
So ca. sollte es sein.

Testen kann ich es nicht, weil auch bei mir Lazarus (im virtuellen PC habe ich es auch) Indy nicht kompilieren möchte. Und so selten dämlich wie das da gemacht ist, hab ich auch keine Lust da länger herumzufummeln. :nixweiss:
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: So 05.02.12 12:51 
Ahhh, vielen Dank!!!

jetzt hab ich nur noch ein aller letztes Problem..
unzwar weiß ich nicht wie ich jetzt genau auf die einzelnen WechselKurse der API zugreifen kann. Um die gehts ja schließlich... Weißt du wie das geht??
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: So 05.02.12 12:59 
In dem XML-Node musst du auch irgendwie die Möglichkeit haben auf die Attribute der Knoten zuzugreifen. Wie musst du mal schauen...
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: So 05.02.12 13:00 
Ahhh, vielen Dank!!!

jetzt hab ich nur noch ein aller letztes Problem..
unzwar weiß ich nicht wie ich jetzt genau auf die einzelnen WechselKurse der API zugreifen kann. Um die gehts ja schließlich... Weißt du wie das geht??

www.ecb.europa.eu/st.../eurofxref-daily.xml

Ich hab das mit der Methone Textknoten einlesen versucht, die hier:

wiki.lazarus.freepas....org/XML_Tutorial/de

beschrieben wird, hatte aber keinen erfolg damit. In der Zeile
ausblenden Delphi-Quelltext markieren
1:
WriteLn(PassNode.NodeValue);

meint der irgentwas von wegen SIGSEGV.. also ein Fehler in dem Benutzen der Klasse, aber wenn es nicht do geht wie auf der Toturial-Seite beschrieben wird, wie soll es dann sonst gehen??
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: So 05.02.12 13:02 
Naja, was erwartest du denn in NodeValue? Der Knoten hat schließlich gar keinen Wert...
Außerdem ist der Knoten USD nicht direkt unter dem DocumentNode, du wirst da also vermutlich gar keinen gefunden haben. Und außerdem musst du das Attribut suchen und nicht den Namen des Knotens...

Es gibt SetAttribute, also wird es vermutlich auch GetAttribute geben. Oder vielleicht gleich Attributes oder so.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: So 05.02.12 16:01 
Also wenn ich in in der Zeile
ausblenden Delphi-Quelltext markieren
1:
PassNode := Doc.DocumentElement.FindNode('USD');

anstadt 'USD', 'cube' eingebe, dann erkennt der auch den nächsten Befehl: WriteLn(PassNode.NodeValue); aber wie muss ich dem sagen, dass ich nur die Werte (also den Wechselkurs) eines bestimmten unterKnotens haben will...
und wie sage ich dann dass der diesen Wert in das Array "Währungen[n]" einträgt???
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Schosch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

WinXP
Lazarus
BeitragVerfasst: Di 07.02.12 11:57 
Ich hab jetzt zwei tage lang versucht auf die unterknoten in dem Knoten 'cube' zuzugreifen, aber egal was ich versucht habe es hat nicht geklappt.. Es kamen immer fehlermeldungen wie: incorect type, oder data coruption und andere... weiß denn keiner wie ich da auf die einzelnen Unterknoten zugreifen kann? ich brauche die wechsel Kurse aus der API:

www.ecb.europa.eu/st.../eurofxref-daily.xml
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
home home