![]() |
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:
Die XML-Datei dazu
XMLDocument1.LoadFromFile('test.xml');
memo2.Text:= XMLDocument1.DocumentElement.ChildValues['name'];
XML-Code:
Jetzt möchte ich aber die aktuelle Levelrotation.xml auslesen und die sieht so aus
<test>
<name>test</name> </test>
XML-Code:
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).
<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> Ich hoffe das dies geht und nicht nur ein XML format des spiels ist. Danke schon jetzt für Antworten. Gruß Red |
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:
Das Progg liest dann aus dieser XML diese Werte aus
<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> -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:
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.
memo1.Lines.Add(FDoc.GetElementsByTagName('level').Item(0).Attributes.GetNamedItem('name').NodeValue[16]);
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 |
Re: Levelrotation.xml auslesbar?
Herzlich willkommen in der Delphi-PRAXiS, Red.
Zerlege den im XML-Dokument gefundenen Text mit Delphi:
Delphi-Quellcode:
Freundliche Grüße vom marabu
function LastWord(const s, delimiters: string): string;
begin Result := AnsiRightStr(s, Length(s) - LastDelimiter(delimiters, s)); end; |
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? |
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:
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.
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; Auf die Zeilen eines Memofeldes kannst du so zugreifen:
Delphi-Quellcode:
Für jeden Befehl, den du nicht genau kennst, liefert dir die Kontexthilfe (F1) in der Delphi-IDE die nötigen Erklärungen.
var
i: Integer; begin for i := 0 to Pred(Memo.Lines.Count) do Memo.Lines[]i := LastWord(Memo.Lines[i], '/'); end; Alles klar? |
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 |
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 :( |
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. |
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. ![]() 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:
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
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;
Delphi-Quellcode:
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:
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; Im Anhang noch die Dateien Gruß Red |
Re: Levelrotation.xml auslesbar?
ok hab das 2te problem jetzt so gelöst:
Delphi-Quellcode:
Nur zum ersten is mir immer noch net viel eingefallen :(
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; |
Re: Levelrotation.xml auslesbar?
Hallo Red,
deine Berechnung der Map-Anzahl lässt sich drastisch vereinfachen:
Delphi-Quellcode:
iLast ist dann der Index der letzten Map.
// überprüfen wieviele maps
iLast := (memo2.Lines.Count - 7) DIV 5; Ich würde es ganz anders machen, aber ich verstehe, dass du bei deinem Code bleiben möchtest. Freundliche Grüße |
Re: Levelrotation.xml auslesbar?
hi Marabu,
genau das habe ich gesucht.... hab ja oben geschrieben das mann es malnehmen könnte :lol: Klar du hättest das Programm bestimmt ganz anderst Angefangen, aber jetzt nochmal was anderes stundenlang zu lesen was dann bestimmt noch kompliezierter ist, wenn du es ja so machen würdest muss es das ja bexstimmt sein ;). Du verstehst ja was ich meine.... Aber großes Dankeschön an dich, ohne deine Hilfe hät ich des echt net hinbekommen. Wenn mann hier durch Forum schaut dann freut mann sich ja schon wenn du antwortest, nach einem komentar von dir kommt meistens: "Super klappt jetzt alles". Deshalb auch von mir :zwinker: Super jetzt klappt alles!!!Ich muss es nur noch zusammen schreiben. Gruß Red |
Re: Levelrotation.xml auslesbar?
Hi Red,
vielen Dank für die Blumen. Zitat:
Freundliche Grüße |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:07 Uhr. |
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