Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] HTML-Reports auswerten mit xpath

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] HTML-Reports auswerten mit xpath

    Hallo,

    ich stehe vor einem Berg von HTML-Dokumenten (ca. 7.000). Bei diesen HTML-Dokumenten handelt es sich um Reports von Messgeräten. Meine Aufgabe ist es jetzt ein Skript zu schreiben, welches diese Dokumente auswertet.

    Bislang habe ich nur sehr wenig DOM-Erfahrung, denke aber das ich mit xpath eher ans Ziel komme als mit Regex oder sonst etwas.

    Im ersten Schritt habe ich mir alle Testbeschreibungen anzeigen lassen die ich mittels xpath ueber /tr/td/b ansprechen kann, in einem HTML-Dokument koennen mehrere 100 Testbeschreibungen auftauchen.

    Fuer die Auswertung benoetigte ich aber nur die Testbeschreibungen deren Testergebnis negativ waren. Diese sind im HTML-Dokument mittels <span class="wrong">wrong</span> gekennzeichnet.

    Diese bekomme ich mittels //span[@class=\'wrong\']

    Das Beispieldokument enthaelt 121 Testbeschreibungen davon waren 23 negativ.

    Als Ergebnis erhalte ich mit meinem nachfolgenden Skript statt der 23 Testbeschreibungen
    2783 Eintraege -> 23 * 121.

    Die beiden xpath-Bedinungen fuer sich betrachtet funktionieren, allerdings scheitere ich bei der Kombination der beiden.

    Irgendwie habe ich mich festgebissen und finde die Loesung nicht...

    PHP-Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <?php
    $html 
    = new DOMDocument();
    $html->loadHtmlFile'report.html' );
    $xpath = new DOMXPath$html );
    /* alle Testbeschreibungen selektieren */
    $testdescs $xpath->query'//tr/td/b' );
    echo 
    "<ol>";
    foreach (
    $testdescs as $testdesc)
    {
      
    /* Testbeschreibungen selektieren deren Ergebnis negativ */
      
    $results $xpath->query'//span[@class=\'wrong\']'$testdesc );
      foreach (
    $results as $result)
      {
        echo 
    "<li>".$testdesc->nodeValue."</li>"
      }
    }
    echo 
    "</ol>";
    ?>
    </html>

  • #2
    Verschachtele nicht die Schleifen, sondern fasse beide Queries zusammen. Das verschachteln scheitert wegen dem // am Anfang der zweiten Query.

    Ohne den HTML-Quelltext zumindest im Ausschnitt zu kennen, ist weitere Hilfestellung leider nicht möglich.

    Gruß Jens

    Kommentar


    • #3
      Danke fuer den Hinweis, aber ich kriege die beiden Queries nicht korrekt kombiniert etwas in dieser Form //tr/td/b/*/span[@class=\'wrong\'] brachte leider nicht das gewuenschte Ergebnis.

      Hier ein Beispieldokument, dass ich deutlich gekuerzt habe.

      Idealerweise wuerde das Skript nur die Zeile TESTBESCHREIBUNG TEST 1 ausgeben...

      Code:
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <title>Temp Lab ac</title>
      </head>
      
      <body>
      
      <div id="wrapper">
      
      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="title">
        <tr bgcolor=green>    
          <td>Temp Lab Profile Index none-german</td>
          <td align="right"><div style="text-transform: uppercase;">passed</div></td>
        </tr>
        
      </table>
      
      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="header">
        <tr>
          <td width="84">Machine</td>
          <td width="12">:</td>
          <td width="269">100000</td>
          <td width="295" align="right">MACHINE SCORE  </td>
          <td width="20"><div style="text-align:center">:</div></td>
          <td width="30">
      	88%</td>
          <td width="70">(434 points)</td>
        </tr>  
        <tr>
          <td>DATE</td>
          <td>:</td>
          <td>01/13/2011 11:29:33</td>
      	
      	<td align="right">MACHINE PASSING SCORE</td><td><div style="text-align:center">:</div></td><td>60%</td><td>(295 points)</td>
      
        </tr>
        <tr>
          <td>TIME ELAPSED </td>
          <td>:</td>
          <td>01:04:17</td>
          <td>&nbsp;</td>
          <td>&nbsp;</td>
          <td>&nbsp;</td>
          <td>&nbsp;</td>
        </tr>
        
        
        
      </table>
      
      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="testdesc">
        <tr>
          <th width="3%" scope="col"><div align="center">No</div></th>
          <th width="78%" scope="col">Test description</th>
          <th width="12%" scope="col"><div align="center">Status</div></th>
          <th width="7%" scope="col"><div align="center">Points</div></th>
        </tr>
        
        <tr><td valign="top" bgcolor="#E9E9E9"><div style="text-align: center; font-weight: bold; margin-top: 2px"> 1 </div></td><td><table width="100%" border="0" cellspacing="0" cellpadding="0" class="split">  <tr><td><b> TESTBESCHREIBUNG TEST 1 </b></td></tr><tr><td> <table width="100%" border="0" cellspacing="0" cellpadding="0" class="split">  <tr>
          <td width="15px" valign="top">&nbsp;</td>
      	
          <td width="15px" valign="top">	
      	<div style="background-color:green ;color:#FFFFFF; text-align:center;padding-bottom: 1px">
      	1
      	</div>
      	
      	</td>
      	
          <td>
       Profil 160
      	</td>
        </tr>  <tr>
          <td width="15px" valign="top">&nbsp;</td>
      	
          <td width="15px" valign="top">	
      	<div style="background-color:green ;color:#FFFFFF; text-align:center;padding-bottom: 1px">
      	2
      	</div>
      	
      	</td>
      	
          <td>
      Profil 180
      	</td>
        </tr>  <tr>
          <td width="15px" valign="top">&nbsp;</td>
      	
          <td width="15px" valign="top">	
      	<div style="background-color:red ;color:#FFFFFF; text-align:center;padding-bottom: 1px">
      	3
      	</div>
      	
      	</td>
      	
          <td>
      Profil 190
      	</td>
        </tr>  <tr>
          <td width="15px" valign="top">&nbsp;</td>
      	
          <td width="15px" valign="top">	
      	<div style="background-color:red ;color:#FFFFFF; text-align:center;padding-bottom: 1px">
      	4
      	</div>
      	
      	</td>
      	
          <td>
      Profil 200
      	</td>
        </tr>  <tr>
          <td width="15px" valign="top">&nbsp;</td>
      	
          <td width="15px" valign="top">	
      	<div style="background-color:green ;color:#FFFFFF; text-align:center;padding-bottom: 1px">
      	5
      	</div>
      	
      	</td>
      	
          <td>
      Profil 210
      	</td>
        </tr>  <tr>
          <td width="15px" valign="top">&nbsp;</td>
      	
          <td width="15px" valign="top">	
      	<div style="background-color:green ;color:#FFFFFF; text-align:center;padding-bottom: 1px">
      	6
      	</div>
      	
      	</td>
      	
          <td>
      Profil 220
      	</td>
        </tr></table> </td></tr></table></td><td valign="top"><div style="text-align: center"> <span class="wrong">wrong</span> </div></td><td valign="top"><div style="text-align: center">  </div></td></tr><tr><td valign="top" bgcolor="#E9E9E9"><div style="text-align: center; font-weight: bold; margin-top: 2px"> 2 </div></td><td><table width="100%" border="0" cellspacing="0" cellpadding="0" class="split">  <tr><td><b>TESTBESCHREIBUNG TEST 2</b></td></tr><tr><td> <table width="100%" border="0" cellspacing="0" cellpadding="0" class="split">  <tr>
          <td width="15px" valign="top">&nbsp;</td>	
          <td width="15px" valign="top"><div style="text-align: center"><img src="img/radio_off.gif" border="0"></div></td>	
          <td><span style="color:black">Profil 300</span></td>
        </tr>  <tr>
          <td width="15px" valign="top"><img src="img/user_answ.gif" border="0"></td>	
          <td width="15px" valign="top"><div style="text-align: center"><img src="img/radio_on.gif" border="0"></div></td>	
          <td><span style="color:green">Profil 350</span></td>
        </tr></table> </td></tr></table></td><td valign="top"><div style="text-align: center"> <span class="correct">correct</span> </div></td><td valign="top"><div style="text-align: center"> 4 </div></td></tr>
          <td width="15px" valign="top"><img src="img/user_answ.gif" border="0"></td>	
      </table></div></body></html>

      Kommentar


      • #4
        Im Beispiel gibts auch keine entspr. Spans in <b>-Tags. Augen auf beim Eierkauf!

        Kommentar


        • #5
          Sorry, verstehe Deine Antwort leider nicht.

          Vermute meine xpath-Query passt nicht zu dem was ich haben will...

          Das Skript soll mit diese Zeile liefern
          TESTBESCHREIBUNG TEST 1

          Code:
          <tr><td><b> TESTBESCHREIBUNG TEST 1 </b></td></tr>
          wenn innerhalb des Tabellenblocks das vorkommt:
          Code:
          <span class="wrong">wrong</span>
          und diesen Eintrag
          Code:
          <tr><td><b> TESTBESCHREIBUNG TEST 2 </b></td></tr>
          ignorieren, wenn innerhalb des Tabellenblocks das vorkommt:
          Code:
          <span class="correct">correct</span>

          Kommentar


          • #6
            Definiere „Tabellenblock“.

            Kommentar


            • #7
              Du müsstest ausgehend vom <span> mit ".." wieder so weit hoch, dass du wieder runter zum <b> kommst, dann sollte es klappen.

              Edit: mit ein wenig probieren:
              Code:
              //span[@class="wrong"]/../../../td[2]//b/text()
              Entwickelt sich mit der Konsole und dem HTML-Tab im Firebug wesentlich bequemer.

              Kommentar


              • #8
                Sorry, ich habe bislang keine Erfahrung mit Xpath bzw. DOM.
                Okay, ich versuche etwas genauer zu beschreiben.

                Das HTML-Dokument in Firebug liefert mir folgende XPath-Informationen:

                fuer die Testbeschreibung:
                /html/body/div/table[3]/tbody/tr[2]/td[2]/table/tbody/tr/td/b

                fuer das Ergebnis des Tests (span class="wrong"):
                /html/body/div/table[3]/tbody/tr[2]/td[3]/div/span

                Wie kriege ich jetzt daraus eine Query, die mir die Testbeschreibung
                liefert wenn <span class="wrong">wrong</span> und die Testbeschreibung
                ignoriert, wenn <span class="correct">correct</span>?

                Kommentar


                • #9
                  Ich habe es eben damit probiert, funktioniert aber auch nicht:

                  PHP-Code:
                  $results $xpath->query'//span[@class=\'wrong\']');
                  echo 
                  "<ol>";
                  foreach (
                  $results as $result)
                  {
                  $testdescs $xpath->query'../../../table/tbody/tr/td/b' );
                  foreach (
                  $testdescs as $testdec)
                    {
                      echo 
                  "<li>".$testdesc->nodeValue."</li>"
                    }
                  }
                  echo 
                  "</ol>"

                  Kommentar


                  • #10
                    Und wie kommst du darauf meinen XPath-Ausdruck zu trennen (vorallem so, dass es nicht funktionieren kann)?

                    Kommentar


                    • #11
                      Sorry. Habe an dem Post so lange rumgeschrieben. Das ich Deinen Edit gar nicht mitbekommen habe.

                      Kommentar


                      • #12
                        Jedenfalls klappt es jetzt.

                        Vielen herzlichen Dank!

                        Kommentar

                        Lädt...
                        X