Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Attribute in XML suchen und ausgeben...Wie? (https://www.delphipraxis.net/108371-attribute-xml-suchen-und-ausgeben-wie.html)

torud 12. Feb 2008 15:29


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:
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;
Aufgerufen wird das bisher so:
Delphi-Quellcode:
ed_msg.Text := GetAttributeValue(XMLContent,'msg');
In dem Edit würde dan Return stehen.

Ich habe nun folgendes versucht, aber meine XML-Kenntnisse sind so Grotte, dass mich das nicht wirklich zum Ziel führt.

Delphi-Quellcode:
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;
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.

Alter Mann 12. Feb 2008 19:12

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:

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;
Ob das jetzt 100% 'ChildNodes' und 'Attributes' unter Delphi heißt weiß bestimmt die Hilfe.

Gruß

marabu 12. Feb 2008 20:24

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:
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;
Freundliche Grüße

torud 13. Feb 2008 04:09

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!

marabu 13. Feb 2008 05:57

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;

himitsu 13. Feb 2008 07:13

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:
<Welcome [color=#ff0000]to the Service[/color]>
aber mir ist so, als wenn man zumindestens den Parameterfehler irgendwie ignorieren lassen kann.


sowas wäre gültiges XML:
Code:
<Welcome to="" the="" Service=""/>
oder
Code:
<Welcome_to_the_Service/>

torud 13. Feb 2008 07:40

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.

shmia 13. Feb 2008 16:28

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 XPath die Attribute ganz bequem auslesen:

Ich weiss jetzt nicht, welcher Parser verwendet wird (und kenne eigentlich nur MSXML) aber hier
mein Vorschlag:
Delphi-Quellcode:
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;
Nachtrag: der XPath-Ausdruck war noch falsch. Danke an marabu.

torud 13. Feb 2008 17:49

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...

shmia 13. Feb 2008 17:57

Re: Attribute in XML suchen und ausgeben...Wie?
 
Zitat:

Zitat von torud
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...

Tja, es gibt verschiedene Parser; je nach dem unterscheiden die die Namen der Interfaces, CoKlassen, ...
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