![]() |
Attribute in XML suchen und ausgeben...Wie?
Hallo Wissende,
ich weiss, es ist sicher einfach ohne Ende, aber ich parse folgenden XML-String seit Ewigkeiten mit ner String-Funktion und will davon nun weg, finde aber leider keinen Weg. Ich weiss schon, dass ich mir wahrscheinlich ein XML-Document erzeugen müsste und mich dann irgendwie durchhangeln muss. So etwas in der Art erhalte ich: <MatchStats id="MS004" matchid="ATP2008WG MS004" seq="118" msg="Return"> Bisher erhalte ich mit dieser Funktion den Inhalt aus den Attributen:
Delphi-Quellcode:
Aufgerufen wird das bisher so:
function GetAttributeValue(XMLContent,Attribute:String):String;
begin if pos(Attribute,XMLContent)<>0 then begin Delete(XMLContent,1,pos(Attribute,XMLContent)+length(Attribute)+1); if pos('"',XMLContent)<>0 then Delete(XMLContent,pos('"',XMLContent),length(XMLContent)); Result:=XMLContent; end; end;
Delphi-Quellcode:
In dem Edit würde dan Return stehen.
ed_msg.Text := GetAttributeValue(XMLContent,'msg');
Ich habe nun folgendes versucht, aber meine XML-Kenntnisse sind so Grotte, dass mich das nicht wirklich zum Ziel führt.
Delphi-Quellcode:
Könnte mir bitte jemand unter die Arme greifen und einen Tipp geben. Ich will die andere Funktion ersetzen, damit ich nicht so viel im QuellCode ändern muss. Deshalb sollten die übergebenen Parameter auch so bleiben. Den Funktionsnamen kann ich später dann noch anpassen.
function GetXmlAttribute(XMLContent, str_Attr : String):String;
var MyXml : IXMLDOMDocument2; Attributes : IXMLDOMNodeList; i : integer; begin MyXml := CoDOMDocument40.Create; MyXml.setProperty('NewParser', true); MyXml.loadXML(XMLContent); Attributes := MyXml.documentElement.selectNodes('MatchStats'); for i:=0 to Attributes.length -1 do if Attributes.item[i].selectSingleNode(str_Attr).nodeName = str_Attr then Result := Attributes.item[i].selectSingleNode(str_Attr).text; end; |
Re: Attribute in XML suchen und ausgeben...Wie?
HI torud,
meine XML-Kenntnisse sind 'nicht' so doll, habe aber unter MS-C# ein ähnlich gelagertes Problem. Ungeprüft nach Delphi könnte es so aussehen:
Delphi-Quellcode:
Ob das jetzt 100% 'ChildNodes' und 'Attributes' unter Delphi heißt weiß bestimmt die Hilfe.function GetXmlAttribute(XMLContent, Attribut : String) : String; var xmlDoc : XmlDocument; root : XmlElement; i, j : Integer; found : Boolean; begin if FileExists(XMLContent) then begin xmlDoc = := CoDOMDocument40.Create; xmlDoc.LoadXML(FileName); root := xmlDoc.DocumentElement; if root.ChildNodes.Count > 0 then begin for i := 0 to root.ChildNodes.Count-1 do begin if (root.ChildNodes[i].Name = "MatchStats") and (root.ChildNodes[i].Attributes.Count -1 > -1) then for j := 0 to root.ChildNodes[i].Attributes.Count -1 do begin if root.ChildNodes[i].Attributes[j].Name = Attribut then begin Result := root.ChildNodes[i].Attributes[j].Value; found := true; Break; end; if found then Break; end; end; end; end; end; Gruß |
Re: Attribute in XML suchen und ausgeben...Wie?
Hallo Tom,
wenn MatchStats das Root-Element darstellt, dann könnte eine Lösung so aussehen:
Delphi-Quellcode:
Freundliche Grüße
function GetAttributeValue(const sElement, sAttribute: string): string;
begin with CoDOMDocument.Create do begin async := False; if LoadXML(sElement) then Result := VarToStr(DocumentElement.getAttribute(sAttribute)) else raise Exception.Create(ParseError.Reason); end; end; const XMP = '<MatchStats id="MS004" matchid="ATP2008WG MS004" seq="118" msg="Return"/>'; procedure TDemoForm.ButtonClick(Sender: TObject); begin ShowMessage(GetAttributeValue(XMP, 'msg')); end; |
Re: Attribute in XML suchen und ausgeben...Wie?
Moin Moin,
das geht schon mal, allerdings nie ohne Exception. Im Projekt Projekt1.exe ist eine Exception der Klasse Exception aufgetreten. Meldung: 'Eine Zeichenfolge wurde erwartet, es konnte aber kein beginnendes Anführungszeichen gefunden werden.'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen. Hast Du vielleicht noch eine Idee was das sein könnte? Also es ist ja so, dass ich diese Inhalte über einen ClientSocket erhalte und parsen soll. Zur Anmeldung beim Server erhalte ich folgendes: <Welcome to the Service> Danach erhalte ich immer nur noch diesen XML-String, der sich inhaltlich in den Attributen ändert. Der String ist normalerweis um einiges länger, wehsalb ich ihn hier mal eingekürzt habe. <MatchStats id="MS004" matchid="ATP2008WG MS004" seq="122" state="P" tim="2008-02-12T08:58:54Z" msg="" score="2/6 3/6 1/0" points="0-30" rnd=" " dbl="1" crt="5" nset="5" stype="1"> Für weitere Tips bedanke ich mich im voraus! |
Re: Attribute in XML suchen und ausgeben...Wie?
Moin Tom,
die Messages sind kein gültiges XML, wenn die Tags nicht auch geschlossen werden.
Delphi-Quellcode:
procedure GetAttributeValues(const sOpenTag: string; list: TStrings);
var i: Integer; map: IXMLDOMNamedNodeMap; begin with CoDOMDocument.Create do begin async := False; if LoadXML(StringReplace(sOpenTag, '>', '/>', [])) then begin list.BeginUpdate; try list.Clear; map := DocumentElement.attributes; for i := 0 to Pred(map.length) do list.Values[map.item[i].nodeName] := VarToStr(map.item[i].nodeValue); finally list.EndUpdate; end; end else raise Exception.Create(ParseError.Reason); end; end; const MSG = '<MatchStats id="MS004" matchid="ATP2008WG MS004" seq="122" state="P" ' + 'tim="2008-02-12T08:58:54Z" msg="" score="2/6 3/6 1/0" points="0-30" ' + 'rnd=" " dbl="1" crt="5" nset="5" stype="1">' ; procedure TDemoForm.ButtonClick(Sender: TObject); begin GetAttributeValues(MSG, ValueListEditor.Strings); end; |
Re: Attribute in XML suchen und ausgeben...Wie?
und laut XML-Definition gibt es keine Werte-losen Parameter und offene Tags müssen als solche gekennzeichnet werden.
Code:
aber mir ist so, als wenn man zumindestens den Parameterfehler irgendwie ignorieren lassen kann.
<Welcome [color=#ff0000]to the Service[/color]>
sowas wäre gültiges XML:
Code:
oder
<Welcome to="" the="" Service=""/>
Code:
<Welcome_to_the_Service/>
|
Re: Attribute in XML suchen und ausgeben...Wie?
Ok, das war mein Fehler. Also die erste Meldung lautet so:
<?xml version="1.0"> <message type="Signon">Welcome to the Service</message> Danach kommen nur noch die anderen Meldungen, wie ich es schon schrieb. |
Re: Attribute in XML suchen und ausgeben...Wie?
Also, man muss zuerst mal aus dem Fragment ein komplettes XML Dokument machen.
Dann kann man mit ![]() Ich weiss jetzt nicht, welcher Parser verwendet wird (und kenne eigentlich nur MSXML) aber hier mein Vorschlag:
Delphi-Quellcode:
Nachtrag: der XPath-Ausdruck war noch falsch. Danke an marabu.
function GetXmlAttribute(XMLContent, Attribut : String) : String;
var xmlDoc : XmlDocument; root, child : XmlElement; node : XmlNode; i, j : Integer; found : Boolean; begin xmlDoc = := CoDOMDocument40.Create; XMLContent := '<?xml version="1.0" encoding="iso-8859-1" standalone="yes">'+ '<root>' + XMLContent+ '</MatchStats></root>'; xmlDoc.LoadXML(XMLContent); // Achtung: hier muss unbedingt eine Fehlerprüfung erfolgen // if xmlDoc.parseError.ErrCode <> 0 then (* Fehler *) root := xmlDoc.DocumentElement; // Wurzel Element holen // wir verwenden einfach XPATH, um das Attribut auszulesen node := root.selectSingleNode('//MatchStats/@'+Attribut); if Assigned(node) then result := node.Value else result := ''; end; |
Re: Attribute in XML suchen und ausgeben...Wie?
Vielen Dank für die Überlassung Deines Codes und Deine Mühe. Kannst Du mir bitte noch mitteilen, welche Units ich noch in die Uses aufnehmen muss, damit es klappt? Meine Delphi-Hilfe kennt XmlDocument, XmlElement, XmlNode nicht...
|
Re: Attribute in XML suchen und ausgeben...Wie?
Zitat:
Ich sehe gerade, du hast wohl mit dem MSXML-Parser angefangen - dann muss man die Unit MSXML2_TLB einbinden. Falls diese Unit nicht vorhanden, muss man sie importieren (Projekt->Typbibliothek importieren...) Dann muss man noch ersetzen: XmlDocument -> IXMLDOMDocument oder IXMLDOMDocument2 XmlElement -> IXMLDOMElement XmlNode -> IXMLDOMNode |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:40 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