Webserver abfragen

Alle Fragen zur Netzwerkkommunikation
catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

BeniBela hat geschrieben:Das sollte auch ganz einfach (für eine bestimmte nagios-Version) mit meinen Internet-Tools gehen; Seite runterladen, HTML zerlegen und bestimmte Stellen suchen ist alles dabei...
Klingt super. Ich werde mir das am Wochenende mal genauer ansehen, leider fehlt mir vorher die Ruhe dazu.

Gruß
Michael

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

BeniBela hat geschrieben:Das sollte auch ganz einfach (für eine bestimmte nagios-Version) mit meinen Internet-Tools gehen; Seite runterladen, HTML zerlegen und bestimmte Stellen suchen ist alles dabei...
Sorry, aber ich begreife einfach nicht wie ich die Tools einsetzen muß.
In uses habe ich den "simplehtmlparser" eingetragen, aber ich weis nicht wie ich jetzt an die Daten im HTML komme.

Hier ist ein Auszug aus der HTML von der ich die Daten herausziehen will:

Code: Alles auswählen

TD CLASS='statusCRITICAL'>CRITICAL</TD>
<TD CLASS='statusBGCRITICAL' nowrap>20-02-2011 11:48:36</TD>
<TD CLASS='statusBGCRITICAL' nowrap> 0d  2h 52m 25s</TD>
<TD CLASS='statusBGCRITICAL'>3/3</TD>
<TD CLASS='statusBGCRITICAL' valign='center'>No route to host </TD>
</TR>
<TR>
<TD></TD>
Dabei interessiert mich u.a.:
CRITICAL
20-02-2011 11:48:36
0d 2h 52m 25s
3/3
No route to host

Kann Du mir bitte ein Beispiel geben wie ich daran komme? Ich vermute hier kommt die procedure parseHTML zum Einsatz, oder?

Gruß
Michael

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Webserver abfragen

Beitrag von BeniBela »

simplehtmlparser ist zu simple, der zerlegt die Datei nur in Tags und Text als Vorverarbeitungsschritt für die anderen Klassen (und hat auch keinen Vorteil gegenüber der lcl)

Am besten nimmst du die Klasse aus extendedhtmlparser, und rufst deren Methoden parseTemplate und parseHTML auf.

Wenn du die ganze Tabellenzeile gepostet hast, wird z.B.: dieses Template funktionieren.

Code: Alles auswählen

<TR htmlparser-optional="true">
<TD CLASS='statusCRITICAL'><htmlparser:read var="status" source="text()"/></TD>
<TD CLASS='statusBGCRITICAL'><htmlparser:read var="date" source="text()"/></TD>
<TD CLASS='statusBGCRITICAL'><htmlparser:read var="time" source="text()"/></TD>
<TD CLASS='statusBGCRITICAL'><htmlparser:read var="count" source="text()"/></TD>
<TD CLASS='statusBGCRITICAL'><htmlparser:read var="message" source="text()"/></TD>
</TR>
(jemand sollte mal einen xml/html-Highlighter im Forum einfügen... )

Wenn es dann eine kritische Zeile gibt, setzt der Parser seine Variablen status, date, time, count, message auf die entsprechenden Werte.

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

BeniBela hat geschrieben:Am besten nimmst du die Klasse aus extendedhtmlparser, und rufst deren Methoden parseTemplate und parseHTML auf.
Ich begreife die Umsetzung nicht. Muß ich jetzt jede der HTML-Zeilen z.B.

Code: Alles auswählen

<TD CLASS='statusBGCRITICAL' nowrap>20-02-2011 11:48:36</TD>
in parseTemplate übergeben?

Wie muß das aufgerufen werden, kannst Du mir das an einem Beispiel zeigen?

Code: Alles auswählen

parseTemplate(template: string; templateName: string='<unknown>');
Gruß
Michael

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Webserver abfragen

Beitrag von BeniBela »

catweasel hat geschrieben:Ich begreife die Umsetzung nicht. Muß ich jetzt jede der HTML-Zeilen z.B.
in parseTemplate übergeben?
Eigentlich kannst dir so ein Template wie einen komplexen regulären Ausdruck vorstellen, der
dann auf die Seite angewandt wird und anschließend alle relevanten Teile in benannten capture-Klammergruppen enthält.
Das heißt du rufst parseTemplate nur einmal auf und übergibst dabei das gesamte Template.
catweasel hat geschrieben: Wie muß das aufgerufen werden, kannst Du mir das an einem Beispiel zeigen?
[/code]
Mit dem Template von oben:

Code: Alles auswählen

parser:=TTemplateHTMLParser.create;
  //Übergebe das gesamte Template
  parser.parseTemplate(
    '<table><TR htmlparser-optional="true">'+
    '<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>'+
    '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="date" source="text()"/></TD>'+
    '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="time" source="text()"/></TD>'+
    '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="count" source="text()"/></TD>'+
    '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="message" source="text()"/></TD>'+
    '</TR></table>');
  //Analysiere die Seite
  parser.parseHTML(  (* ... String der die gesamte html Datei enthält *));
  //Auswerten
  if parser.variables.values['status'] <> '' then begin
    //...
    writeln('Es gibt ein kritisches System, Meldung ',   parser.variables.values['message']);
    for i:=0 to parser.variables.count-1 do writeln('  ',parser.variables.names[i], ': ',parser.variables.valuefromindex[i]);
  end;

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

BeniBela hat geschrieben: //Auswerten
if parser.variables.values['status'] <> '' then begin
//...
writeln('Es gibt ein kritisches System, Meldung ', parser.variables.values['message']);
for i:=0 to parser.variables.count-1 do writeln(' ',parser.variables.names, ': ',parser.variables.valuefromindex);
end;[/code]

Danke, ich denke jetzt wird es klarer. :)
Sehe ich das richtig das dann aber z.B. jedes 'status' nur einmal pro Seite möglich ist, oder? Ich kann nämlich nicht vorhersagen wie oft das in meiner Seite vorkommt, das variiert ständig da die Seite (*.cgi) erst beim Aufruf erstellt wird.

Gruß
Michael

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Webserver abfragen

Beitrag von BeniBela »

catweasel hat geschrieben: Sehe ich das richtig das dann aber z.B. jedes 'status' nur einmal pro Seite möglich ist, oder? Ich kann nämlich nicht vorhersagen wie oft das in meiner Seite vorkommt, das variiert ständig da die Seite (*.cgi) erst beim Aufruf erstellt wird.
Nein, das funktioniert auch, nur das Auslesen der Variablen wird etwas umständlicher.
Wenn du <htmlparser:loop>..</htmlparser:loop> ins Template einfügst, wird alles dazwischen so oft wie möglich wiederholt (so dass z.B.: <table><htmlparser:loop><tr>...</tr></htmlparser:loop> alle Zeilen in einer Tabelle findet, <htmlparser:loop><table><tr>..</tr></table></htmlparser:loop> jeweils eine Zeile aller Tabelle und <htmlparser:loop><tr></tr></htmlparser:loop> alle Zeilen in allen Tabellen)
Und jeder Änderung einer Variablen wird in der Eigenschaft variablesChangeLog gespeichert (beinahe so als wäre jede Variable ein Unix-Stream).

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

Also irgenwie klappt das nicht bei mir. :cry:

Ich habe das jetzt wie folgt bei mir eingetragen:
Zunächst wird die Seite abgeholt (das funktioniert soweit) und dem Parser übergeben, zur Kontrolle wird das ganze noch mal in ein Memofeld übertragen. Dort kann man die HTML-Seite sehen.
Die if-Abfrage

Code: Alles auswählen

if parser.variables.values['status'] <> '' then begin
wird aber nicht angesprungen da showmessage nichts anzeigt und auch das Memo3-Feld leer bleibt.
Ich habe hier mal eine komplette html-Datei angehängt, so wie ich sie von Nagios zurück bekomme.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  Str: TStringStream;
  Url: String;
  parser:THtmlTemplateParser;
  i:integer;
begin
  Url := 'http://192.168.1.105/nagios/cgi-bin/status.cgi?host=all&servicestatustypes=28&noheader';
  Str := TStringStream.Create('');
  try
    if not HttpGetBinary( Url, Str ) then ShowMessage('Fehler!'); 
 
    parser:=THtmlTemplateParser.create;
      //Übergebe das gesamte Template
      parser.parseTemplate(
        '<table><TR htmlparser-optional="true">'+
        '<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="date" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="time" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="count" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="message" source="text()"/></TD>'+
        '</TR></table>');
      //Analysiere die Seite
      parser.parseHTML(Str.DataString);
 
      //Zur Kontrolle noch in ein Memofeld
      Memo1.Lines.Add( Str.DataString );
 
      //Auswerten
      if parser.variables.values['status'] <> '' then begin
        //Ausgabe in ein anderes Memofeld
        showmessage('Auswertung wird nicht ausgeführt');
        Memo3.Lines.Add('Es gibt ein kritisches System, Meldung '+parser.variables.values['message']);
        for i:=0 to parser.variables.count-1 do Memo3.Lines.Add('  '+parser.variables.names[i]+': '+parser.variables.valuefromindex[i]);
        //writeln('Es gibt ein kritisches System, Meldung ',   parser.variables.values['message']);
        //for i:=0 to parser.variables.count-1 do writeln('  ',parser.variables.names[i], ': ',parser.variables.valuefromindex[i]);
      end;
 
  finally
    Str.Free;
  end;
end;
Dateianhänge
status.zip
Status.html
(1.96 KiB) 105-mal heruntergeladen

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Webserver abfragen

Beitrag von BeniBela »

catweasel hat geschrieben: Die if-Abfrage

Code: Alles auswählen

if parser.variables.values['status'] <> '' then begin
wird aber nicht angesprungen da showmessage nichts anzeigt und auch das Memo3-Feld leer bleibt.
Es funktioniert, wenn du den Table-Tag aus dem Template entfernst oder das htmlparser-optional="true" Attribut. (und das ist wirklich seltsam, denn eigentlich sollte das optional-Attribut *niemals* zu weniger Fundstellen führen)
Und alle Meldungen werden zurückgegeben, wenn <table><TR htmlparser-optional="true"> durch <htmlparser:loop><tr> ersetzt wird.
catweasel hat geschrieben: Ich habe hier mal eine komplette html-Datei angehängt, so wie ich sie von Nagios zurück bekomme.
Über 160 Fehler, schreckliches Ding

(aber die TDs sind hübsch in einzelnen Zeilen, da kannst du alternativ auch mit regex nach CLASS='statusCRITICAL' suchen)

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

BeniBela hat geschrieben:Und alle Meldungen werden zurückgegeben, wenn <table><TR htmlparser-optional="true"> durch <htmlparser:loop><tr> ersetzt wird.
Irgendwo ist da noch ein Wurm. Ich bekomme trotz "htmlparser:loop" immer nur den letzten CRITICAL ins Memofeld.
Muß die for i:= Schleife noch erweitert werden wenn es sich um mehrere Treffer handeln kann?

Code: Alles auswählen

parser.parseTemplate(
          '<htmlparser:loop><TR>'+
          '<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="date" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="time" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="count" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="message" source="text()"/></TD>'+
          '</TR></htmlparser:loop>');
        //Analysiere die Seite
        parser.parseHTML(Response.Text);
 
        //Zur Kontrolle noch in ein Memofeld
        Memo2.Lines.Add( Response.Text );
 
        //Auswerten
        if parser.variables.values['status'] <> '' then begin
          //Ausgabe in ein anderes Memofeld
          Memo3.Lines.Add('Es gibt ein kritisches System, Meldung '+parser.variables.values['message']);
          for i:=0 to parser.variables.count-1 do Memo3.Lines.Add('  '+parser.variables.names[i]+': '+parser.variables.valuefromindex[i]);
        end;

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Webserver abfragen

Beitrag von BeniBela »

catweasel hat geschrieben: Muß die for i:= Schleife noch erweitert werden wenn es sich um mehrere Treffer handeln kann?
Du musst parser.variables durch parser.variableChangeLog ersetzen (variables enthält von jeder Variable nur den letzten Wert)

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

BeniBela hat geschrieben:
catweasel hat geschrieben: Muß die for i:= Schleife noch erweitert werden wenn es sich um mehrere Treffer handeln kann?
Du musst parser.variables durch parser.variableChangeLog ersetzen (variables enthält von jeder Variable nur den letzten Wert)
Prima, jetzt funktioniert es schon fast so wie es haben wollte. Ich muß nur noch je Meldung zwei weitere Daten aus der Seite heraussuchen (den Host den die Warnung betrifft und den Service der angemeckert wird)

Bis hierher schon mal vielen Dank für die Hilfe :)
Gruß
Michael

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

Moin

Ich habe immer noch Probleme.

Die Informationen stehen ja in etwa wie folgt auf der Webseite die ich abfrage:

Code: Alles auswählen

<Rechnername>  <Service>  <Status>  <LastCheck>  <Duration>  <Attempt>  <Infotext>
               <Service>  <Status>  <LastCheck>  <Duration>  <Attempt>  <Infotext>
               <Service>  <Status>  <LastCheck>  <Duration>  <Attempt>  <Infotext>
                ...
 
<Rechnername>  <Service>  <Status>  <LastCheck>  <Duration>  <Attempt>  <Infotext>
               <Service>  <Status>  <LastCheck>  <Duration>  <Attempt>  <Infotext>
               <Service>  <Status>  <LastCheck>  <Duration>  <Attempt>  <Infotext>
                ...
wie man sieht steht der Rechnername immer nur einmal in der ersten Zeile.

Wenn ich die Seite wie nachstehend auslese, bekomme ich nur die Zeile mit Rechnernamen:

Code: Alles auswählen

'<htmlparser:loop><TR>'+
        '<TD CLASS="statusHOSTDOWN"><htmlparser:read var="host" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="service" source="text()"/></TD>'+
        '<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="last_check" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="duration" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="attempt" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="status_information" source="text()"/></TD>'+
        '</TR></htmlparser:loop>');
Wenn ich sie dagegen ohne den Host-Teil auslese, fehlt mir der Hostname:

Code: Alles auswählen

parser.parseTemplate(
          '<htmlparser:loop><TR>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="service" source="text()"/></TD>'+
          '<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="last_check" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="duration" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="attempt" source="text()"/></TD>'+
          '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="status_information" source="text()"/></TD>'+
          '</TR></htmlparser:loop>');
Danach dachte ich ich bin mal clever und schreibe die beiden Teile nacheinander.
Ergebnis: Erst bekomme ich die beiden Zeilen mit Rechnernamen zurück und dann alle Einträge ohne den Namen. :evil:



Der ganze Bock mit einer Fehlerzeile sieht ja in etwa immer so aus:

Code: Alles auswählen

<TD ALIGN=LEFT valign=center CLASS='statusBGCRITICAL'><A HREF='extinfo.cgi?type=2&host=Netbook&service=NSClient%2B%2B+Version'>NSClient++ Version</A></TD></TR>
</TABLE>
</TD>
<TD ALIGN=RIGHT CLASS='statusBGCRITICAL'>
<TABLE BORDER=0 cellspacing=0 cellpadding=0>
<TR>
</TR>
</TABLE>
</TD>
 
</TR></TABLE></TD>
<TD CLASS='statusCRITICAL'>CRITICAL</TD>
<TD CLASS='statusBGCRITICAL' nowrap>13-02-2011 16:57:41</TD>
<TD CLASS='statusBGCRITICAL' nowrap> 0d  8h 26m  3s</TD>
<TD CLASS='statusBGCRITICAL'>3/3</TD>
<TD CLASS='statusBGCRITICAL' valign='center'>No route to host </TD>
</TR>
Komme ich da mit dem Parser irgendwie an die erste Zeile mit dem

Code: Alles auswählen

<A HREF='extinfo.cgi?type=2&host=Netbook&service=
heran? Da steht ja immer der Hostname (hier Netbook) drin, den könnte ich dann irgendwie herausextrahieren. Das Problem für mich besteht darin diese Info mit den HREF=... erst einmal zu bekommen.
Ich hoffe ich hab´s nicht zu kompliziert erklärt.. :oops:

Gruß
Michael

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Webserver abfragen

Beitrag von BeniBela »

Der Parser ist super flexibel, da gibt es viele Möglichkeiten.
Zum Beispiel kannst du im source-Attribut XPath verwenden, und damit so den Link auslesen:

Code: Alles auswählen

<htmlparser:loop><TR>
<TD CLASS="statusBGCRITICAL">
   <a>
       <htmlparser:read var="service" source="text()"/>
       <htmlparser:read var="servicelink" source="@href"/>
   </a>
</TD>
<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="last_check" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="duration" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="attempt" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="status_information" source="text()"/></TD>
</TR></htmlparser:loop>
Oder du kannst XPath mit einem regulären Ausdruck verwenden, der gleich den Hostname rausfiltert:

Code: Alles auswählen

<htmlparser:loop><TR>
<TD CLASS="statusBGCRITICAL">
   <a>
       <htmlparser:read var="service" source="text()"/>
       <htmlparser:read var="hostname" source="filter(@href, 'host=([^&]+)&', '1') "/>
   </a>
</TD>
<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="last_check" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="duration" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="attempt" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="status_information" source="text()"/></TD>
</TR></htmlparser:loop>
Oder du kannst auch eine temporäre Variable verwenden (wenn es den Link nicht gäbe):

Code: Alles auswählen

<htmlparser:loop><TR>
<td><htmlparser:if test="text() != ''"><htmlparser:read var="temphostname" source="text()"/></htmlparser:if></td>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="hostname" source="$temphostname;"/><htmlparser:read var="service" source="text()"/></TD>
<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="last_check" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="duration" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="attempt" source="text()"/></TD>
<TD CLASS="statusBGCRITICAL"><htmlparser:read var="status_information" source="text()"/></TD>
</TR></htmlparser:loop>

[edit:] schön, das Forum hat doch einen xml-Highlighter. Übrigens ist der Grund dafür, dass es am Anfang mit dem optional-Attribut nicht funktioniert hat, dass der Parser doch nicht global greedy, sondern nur lokal greedy ist.

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Webserver abfragen

Beitrag von catweasel »

Das haut irgendwie nicht hin. Bei dem ersten Beispiel wo der Servicelink zurückgegeben werden soll
bekomme ich eine Debugger-Nachricht mit dem Text:
"The tag <A> was closed, but the latest opend was <TR>"
Das ist doch Mist. Als <A> geschlossen wurde war <A> auch als letztes geöffnet worden?!

Code: Alles auswählen

parser.parseTemplate(
        '<htmlparser:loop><TR>'+
        '<TD CLASS="'+
           '<A>'+
              '<htmlparser:read var="service" source="text()"/>'+
              '<htmlparser:read var="servicelink" source="@href"/>'+
           '</A>'+
        '</TD>'+
        '<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="last_check" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="duration" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="attempt" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="status_information" source="text()"/></TD>'+
        '</TR></htmlparser:loop>');
und beim zweiten Beispiel:

Code: Alles auswählen

parser.parseTemplate(
        '<htmlparser:loop><TR>'+
        '<TD CLASS="statusBGCRITICAL">'+
	   '<A>'+
		'<htmlparser:read var="service" source="text()"/>'+
		'<htmlparser:read var="hostname" source="filter(@href, "host=([^&]+)&", "1") "/>'+
	   '</A>'+
        '</TD>'+
        '<TD CLASS="statusCRITICAL"><htmlparser:read var="status" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="last_check" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="duration" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="attempt" source="text()"/></TD>'+
        '<TD CLASS="statusBGCRITICAL"><htmlparser:read var="status_information" source="text()"/></TD>'+
        '</TR></htmlparser:loop>');

gibt es die folgende Debugger-Nachricht:
"Pseudo-XPath parsing ended on wrong level: at filter(@href, on level:
in: filter(@href,[<-fehler]"

Ich sitze seit Minuten vor der Fehlermeldung und habe keinen Dunst was sie mir sagen will.... :cry:

Antworten