Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Levelrotation.xml auslesbar? (https://www.delphipraxis.net/107319-levelrotation-xml-auslesbar.html)

redeyes330 25. Jan 2008 17:59


Levelrotation.xml auslesbar?
 
Hallo zusammen

Ich kenne mich nicht besonders mit Delphi aus und möchte auch nur ein kleines Programm machen zum Steuern meines Gameservers über FTP. Das Wissen das ich dafür benötige habe ich eigentlich.
Ich benutze Turbo Delphi und für die XML Sachen ein TXMLDocument.

Ich habe nachgelesen wie man aus einer XML datei Werte ausliest.

Code:
XMLDocument1.LoadFromFile('test.xml');
memo2.Text:= XMLDocument1.DocumentElement.ChildValues['name'];
Die XML-Datei dazu

XML-Code:
<test>
   <name>test</name>
</test>
Jetzt möchte ich aber die aktuelle Levelrotation.xml auslesen und die sieht so aus

XML-Code:
<levelrotation>
<level name="multiplayer/ps/Plantation" gamerules="PowerStruggle">
<setting setting="g_timelimit 30"/>
<setting setting="g_revivetime 15"/>
<setting setting="g_fraglimit 0"/>
</level>
<level name="multiplayer/ia/Steelmill" gamerules="InstantAction">
<setting setting="g_timelimit 90"/>
<setting setting="g_revivetime 15"/>
<setting setting="g_fraglimit 0"/>
</level>
</levelrotation>
Wie kann ich jetzt hier die wörter bzw zahlen auslesen? Also Den Mapnamen (Plantation und Steelmill), die Zeiten (30, 15, 0 usw) und den Mod(PowerStrugle oder InstatnAction).
Ich hoffe das dies geht und nicht nur ein XML format des spiels ist.
Danke schon jetzt für Antworten.

Gruß Red

redeyes330 26. Jan 2008 14:42

Re: Levelrotation.xml auslesbar?
 
hallo nochmal...

ich habe jetzt mal anstatt dem TXMLDocument eine DomImplementation und einen XmlToDomParser benutzt und muss sagen das ich schon ein Stück weiter gekommen bin. Ich kann die XML Datei zwar auslesen mit folgendem Code:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  FDoc: TDomDocument;
begi
  FDoc := XMLToDomParser1.ParseFile('levelrotation.xml', False);
  memo1.Lines.Clear;
memo1.Lines.Add(FDoc.GetElementsByTagName('level').Item(0).Attributes.GetNamedItem('name').NodeValue);
memo1.Lines.Add(FDoc.GetElementsByTagName('setting').Item(0).Attributes.GetNamedItem('setting').NodeValue);
memo1.Lines.Add(FDoc.GetElementsByTagName('setting').Item(1).Attributes.GetNamedItem('setting').NodeValue); memo1.Lines.Add(FDoc.GetElementsByTagName('setting').Item(2).Attributes.GetNamedItem('setting').NodeValue);

end;

XML-Code:
<levelrotation>
<level name="multiplayer/ps/Beach" gamerules="PowerStruggle">
<setting setting="g_timelimit 90"/>
<setting setting="g_revivetime 15"/>
<setting setting="g_fraglimit 0"/>
</level>
<level name="multiplayer/ps/Plantation" gamerules="PowerStruggle">
<setting setting="g_timelimit 30"/>
<setting setting="g_revivetime 15"/>
<setting setting="g_fraglimit 0"/>
</level>
</levelrotation>
Das Progg liest dann aus dieser XML diese Werte aus
-multiplayer/ps/Beach
-g_timelimit 90
-g_revivetime 15
-g_fraglimit 0

Jetzt möchte ich aber nicht "multiplayer/ps/Beach" sondern nur "Beach" da stehen haben.
Wie kann ich eine Reihe von Buchstaben auslesen? Also nur das "B" von "Beach" bekomm ich auch noch hin :wink:

Delphi-Quellcode:
memo1.Lines.Add(FDoc.GetElementsByTagName('level').Item(0).Attributes.GetNamedItem('name').NodeValue[16]);
Aber eine Rheienfolge funkzt iwie nicht. Vorallen sind die Mapnamen auch nicht immer glaich lang. Was kann ich da machen? Habe Schon an sowas wie "for i := 16 to Nodes.length - 1 do" gedacht, aber wie schon geschrieben ich kenne micht damit nicht aus.

Ich hoffe jemand kann mir das trotzdem kurz erklären oder ein link von einem guten Anfängertut geben. Die meisten Tuts sind ja echt nicht zu entschlüsseln für Anfänger wie mich ;)

Danke im Voraus für jede Antwort

Gruß Red

marabu 26. Jan 2008 15:28

Re: Levelrotation.xml auslesbar?
 
Herzlich willkommen in der Delphi-PRAXiS, Red.

Zerlege den im XML-Dokument gefundenen Text mit Delphi:

Delphi-Quellcode:
function LastWord(const s, delimiters: string): string;
begin
  Result := AnsiRightStr(s, Length(s) - LastDelimiter(delimiters, s));
end;
Freundliche Grüße vom marabu

redeyes330 26. Jan 2008 17:03

Re: Levelrotation.xml auslesbar?
 
Hallo

Danke ersteinmal für deine Antwort. So etwas habe ich gesucht, jedoch weiß ich nicht wie ich das jetzt schreiben kann. Giebt es da vllt ein Tutorial oder so etwas? So wie ich das Vestehe ist result dan das gefilterte wort?! :wall:

Aber ich kenn mich damit zu wenig aus um daraus jetzt etwas zu schreiben was mir hilft :(
Kannst du das vllt etwas genauer beschreiben wie ich aus meinemMemofeld eine Zeile mit dieser Funktion filtere?

Achja und das "AnsiRightStr" ist bei mir rot unterstrichen. Muss da joch eine uses verwendet werden?

marabu 26. Jan 2008 17:56

Re: Levelrotation.xml auslesbar?
 
Wenn du AnsiRightStr() in der Indexsuche deiner Delphi-Hilfe eingibst, dann nennt dir das entsprechende Hilfekapitel auch den Unit-Namen, den du unter uses angeben musst: StrUtils.

Die Funktion LastWord() kann man zum besseren Verständnis wieder entflechten:

Delphi-Quellcode:
function LastWord(const s, delimiters: string): string;
var
  iPos, iLength: Integer;
begin
  iPos := LastDelimiter(delimiters, s);
  iLength := Length(s) - iPos;
  Result := AnsiRightStr(s, iLength);
end;
Zuerst wird die (1-basierende) Position des letzten Delimiters "/" gesucht. Dann wird die Länge des letzten Wortes "Beach" berechnet und zuletzt werden genau soviele Zeichen am rechten Ende des übergebenen Strings als Ergebnis des Funktionsaufrufs zurückgegeben.

Auf die Zeilen eines Memofeldes kannst du so zugreifen:

Delphi-Quellcode:
var
  i: Integer;
begin
  for i := 0 to Pred(Memo.Lines.Count) do
    Memo.Lines[]i := LastWord(Memo.Lines[i], '/');
end;
Für jeden Befehl, den du nicht genau kennst, liefert dir die Kontexthilfe (F1) in der Delphi-IDE die nötigen Erklärungen.

Alles klar?

redeyes330 26. Jan 2008 18:29

Re: Levelrotation.xml auslesbar?
 
Hi marabu

Jetzt vesteh ich das schon vesser ;). Danke für deine Mühe. Ich habe das jetzt soweit hinbekommen, dass ich die mapnamen aus der XML indas Memo lade und danch aus dem Memo die Mapnamen. Ich vesuche jetzt das selbe noch für die Zeiten usw zu schreiben. Wenn ich da nicht weiterkomme melde ich mich nochmal.

Aber großes THX an dieser Stelle.

Gruß Red

redeyes330 26. Jan 2008 22:31

Re: Levelrotation.xml auslesbar?
 
Ich bin jetzt schon ein Stück weiter(Für meine Verhältnisse xD)
Aber nun habe ich das Problem das ich die Levelrotation zuerst in ein Memo reinlade und dann alle Elemente Namens level durchsuche in einer schleife. Da aber nur in jeder5ten Zeile eine Map steht wollte ich die Zeilen der Levelrotation durch 5 teilen oder halt mit 0.2 malnehmen.

Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
var
  FDoc: TDomDocument;
  i: Integer;
begin
  memo2.Lines.Clear;
  memo2.Lines.LoadFromFile('levelrotation.xml');
  FDoc := XMLToDomParser1.ParseFile('levelrotation.xml', False);

  for i := 0 to Pred(Memo2.Lines.Count)-3 do //<--hier sollte sowas wie Pred(Memo2.Lines.Count)-3*0.2 do
  memo1.Lines.Add(FDoc.GetElementsByTagName('level').Item(i).Attributes.GetNamedItem('name').NodeValue);

end;

Ach ja da in der Levelrotation noch 2 Zeilen mehr sind immer habe ich statt -1 -3 genommen.Aber weiter komme ich nicht. Wenn ich für eine Levelrotation die Zeilen ausreche und in dem Fall -18 mache geht das. Aber es können ja mal 3 maps also 15 Zeilen+2die immer da sind, aber auch mal 5 maps also 25 Zeilen+2 die immer da sind.
Ich habe schon gesucht aber nichts passendes gefunden :(

marabu 27. Jan 2008 09:44

Re: Levelrotation.xml auslesbar?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Immer wenn du ein Problem lösen möchtest, dann fragst du dich: Wovon kann ich ausgehen? Was will ich erreichen? Beim Programmieren nennt man diesen Strukturansatz IPO (Input-Process-Output) oder EVA (Eingabe-Verarbeitung-Ausgabe). Ich sehe deine Eingabe (levelrotation.xml), aber nicht die gewünschte Ausgabe. So kann ich dir höchstens Syntaxfehler und die gröbsten Schnitzer korrigieren. Besser du beschreibst auch die gewünschte Ausgabe.

Ich hänge dir mal eine einfache Demo an, mit der du dein XML-Dokument laden und auf einzelne Elemente und Attribute zugreifen kannst. Vielleicht hilft dir das Studium des Codes ein wenig bei deinem Vorhaben.

redeyes330 30. Jan 2008 12:18

Re: Levelrotation.xml auslesbar?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo nochmal,

Mein Programm soll Wie folgt aussehen. Auf dem FTP meines Gameservers sind 2 XML-Dateien und 3 cfg-Dateien. Die CFG`s enthalten Verschiedene einstellungen. Die Einstellungen sind in Zeilen unterteilt. Das Programm soll nun in einem Advance Modus starten, sich mit dem FTP Verbinden und die CFG`s und die XML`s in memofelder einlesen.Soweit hatte selbst ich keine Probleme ;)

Das ganze ist natürlich auch veränderbar um es wieder zu speichern und hochzuladen.

Jetzt habe ich das Programm mit einem Basic Modus erweitert. In diesem Modus sollen nicht die CFG`s und XML`s in memofelder, sondern Nur die Zahlen oder Worte der Jeweiligen Settings sollen in ein Edit feld.

Damit man sich das auch mal Vorstellen kann hier ein Bild von Vorhaben. Das "neue Programm" sollte in etwa gleich sein, nur sollen diesmal nicht nur die Dateien geschrieben werden, sondern auch der Basicmodus mit den einstellungen in den Dateien geladen werden.

http://people.freenet.de/redeyes330/progg.jpg

den Normalen Modus habe ich fertig. Den Basic Modus für den Mapcycle auch fast und mit dem speichern der CFG`s hab ich auch noch keine Probleme.

Meine Probleme:

1. Wenn ich die Maps in eine listbox wie auf dem Bild schreibe, soll das Programm So viele XML-nodes in der xml suchen , wie auch maps vorhanden sind. Ich habe das jetzt so gelöst aber gleichzeitig auf eine Map anzahl von 16 begrenzen müssen.
Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
var
  i, j, anzahl: Integer;
begin
//ftp connecten
  ftp := TInetFTP.Create;
  ftp.server:= '81.3.59.69';
  ftp.User:= 'server4656';
  ftp.Password:= 'xxxx';
  ftp.Connect(true);
//levelrotation und maplist runterladen
  ftp.GetFile('server4656/levelrotation.xml', 'levelrotation.xml');
  ftp.GetFile('server4656/maplist.xml', 'maplist.xml');
//server starten
  form3.WebBrowser1.Navigate('http://server4656:xxxx@81.3.59.69:46569/start');
//levelrotation.xml laden
  memo2.Lines.Clear;
  memo2.Lines.LoadFromFile('levelrotation.xml');
  FDoc := XMLToDomParser1.ParseFile('levelrotation.xml', False);
  try
  i:= memo2.Lines.Count;
//überprüfen wieviele maps
  if i= (7) then
  anzahl:= (i-7);
  if i= (12) then
  anzahl:= (i-11);
  if i= (17) then
  anzahl:= (i-15);
  if i= (22) then
  anzahl:= (i-19);
  if i= (27) then
  anzahl:= (i-23);
  if i= (32) then
  anzahl:= (i-27);
  if i= (37) then
  anzahl:= (i-31);
  if i= (42) then
  anzahl:= (i-35);
  if i= (47) then
  anzahl:= (i-39);
  if i= (52) then
  anzahl:= (i-43);
  if i= (57) then
  anzahl:= (i-47);
  if i= (62) then
  anzahl:= (i-51);
  if i= (67) then
  anzahl:= (i-55);
  if i= (72) then
  anzahl:= (i-59);
  if i= (77) then
  anzahl:= (i-63);
  if i= (82) then
  anzahl:= (i-67);
//Maps mit Pfad in memo
  for i := 0 to (anzahl) do
  memo1.Lines.Add(FDoc.GetElementsByTagName('level').Item(i).Attributes.GetNamedItem('name').NodeValue);
  except
  ShowMessage('Fehler mit der Levelrotation');
  end;
//letzet wort, nur Mapnamen
  for i := 0 to Pred(Memo1.Lines.Count) do
  Memo1.Lines[i] := LastWord(Memo1.Lines[i], '/');
//Mapnamen in die ListBox
  for i := 0 to Pred(Memo1.Lines.Count) do
  listbox1.Items.Add(memo1.Lines[i]);
  FDoc.Free;
2. Ich weiß nicht wie ich das mit der CFG-Datei machen kann. Ich habe jetzt folgendes Versucht mit dem ergebniss das ich die einstellungen auslesen kann. Jedoch soll das Programm ja nach einem bestimmten wort z.B servername suchen und dann die einstellung hinter dem wort, also Drachen-Gilde.com in ein Editfeld schreiben
Delphi-Quellcode:
function Without(const s: string; charSet: TSysCharSet): string;
var
  i, iDel: Integer;
begin
  Result := s;
  iDel := 0;
  for i := 1 to Length(s) do
    if not (s[i] in charSet)
      then Result[i - iDel] := s[i]
      else Inc(iDel);
  SetLength(Result, Length(s) - iDel);
end;

function LastWord(const s, delimiters: string): string;
var
  iPos, iLength: Integer;
begin
  iPos := LastDelimiter(delimiters, s);
  iLength := Length(s) - iPos;
  Result := AnsiRightStr(s, iLength);
end;

procedure TForm1.FormShow(Sender: TObject);
const
  DIGITS = ['"'];
begin

  memo1.Lines.LoadFromFile('server.cfg');

  for i := 0 to Pred(Memo1.Lines.Count) do
  memo2.Lines.Add(Without(Memo1.Lines[i], DIGITS));
  for i := 0 to Pred(Memo1.Lines.Count) do
  memo3.Lines.Add(LastWord(Memo2.Lines[i], ' ='));

end;
3. Naja das ist mehr eine bitte ;). Da ich das was ich im mom benutze so ziemlich verstehe wäre es net schlecht wenn mann es auch so in der Art machen könnte. Auch wenn es etwas länger ist, Hauptsache ich versteh das Programm auch noch ohne das ich mich in die tiefen abgründe von Delphi stürzen muss. :wiejetzt:

Im Anhang noch die Dateien

Gruß Red

redeyes330 30. Jan 2008 13:05

Re: Levelrotation.xml auslesbar?
 
ok hab das 2te problem jetzt so gelöst:

Delphi-Quellcode:
function Without(const s: string; charSet: TSysCharSet): string;
var
  i, iDel: Integer;
begin
  Result := s;
  iDel := 0;
  for i := 1 to Length(s) do
    if not (s[i] in charSet)
      then Result[i - iDel] := s[i]
      else Inc(iDel);
  SetLength(Result, Length(s) - iDel);
end;

function LastWord(const s, delimiters: string): string;
var
  iPos, iLength: Integer;
begin
  iPos := LastDelimiter(delimiters, s);
  iLength := Length(s) - iPos;
  Result := AnsiRightStr(s, iLength);
end;

procedure TForm1.FormShow(Sender: TObject);
const
  DIGITS = ['"'];
  var
  t1, t2, t3: String;
begin

  memo1.Lines.LoadFromFile('server.cfg');

  for i := 0 to Memo1.Lines.Count - 1 do
  begin
  if Pos('servername' , Memo1.Lines.Strings[i]) <> 0 then
  t1:= Memo1.Lines.Strings[i];
  t2:= Without(t1, DIGiTS);
  t3:= LastWord(t2, '=');
  edit1.Text:= t3

  end;
Nur zum ersten is mir immer noch net viel eingefallen :(


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:56 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz