XPath Traverse: Moving outside of tbody to the next row

Viewed 85

I'm trying to select a row that is after a tbody

<tbody style="page-break-inside: avoid">
  <tr>
    <td style="" id="column1" valign="top"></td>
    <td style="" id="column2" valign="top" class="style3">ELEMENT1</td>
    <td style="" id="column3" valign="top" class="style2">ELEMENT2</td>
    <td style="" id="column4" valign="top" colspan="2" class="style2"><a target="_blank" href="#">ELEMENT 3</a></td>
    <td style="" id="column6" valign="top"></td>
    <td style="" id="column7" valign="top"></td>
    <td style="" id="column8" valign="top"></td>
  </tr>
  <tr>
    <td style="" id="column1" valign="top"></td>
    <td style="" id="column2" valign="top"></td>
    <td style="" id="column3" valign="top"></td>
    <td style="" id="column4" valign="top"></td>
    <td style="" id="column5" valign="top" class="style3">ELEMENT 4</td>
    <td style="" id="column6" valign="top"></td>
    <td style="" id="column7" valign="top"></td>
    <td style="" id="column8" valign="top"></td>
  </tr>
  <tr>
    <td style="" id="column1" valign="top"></td>
    <td style="" id="column2" valign="top"></td>
    <td style="" id="column3" valign="top"></td>
    <td style="" id="column4" valign="top" class="style7"></td>
    <td style="" id="column5" valign="top" class="style3"></td>
    <td style="" id="column6" valign="top"></td>
    <td style="" id="column7" valign="top"></td>
    <td style="" id="column8" valign="top"></td>
  </tr>
</tbody>

<tr>
  <td style="" id="column1" valign="top"></td>
  <td style="" id="column2" valign="top"></td>
  <td style="" id="column3" valign="top"></td>
  <td style="" id="column4" valign="top"></td>
  <td style="" id="column5" valign="top"></td>
  <td style="" id="column6" valign="top"></td>
  <td style="" id="column7" valign="top"></td>
  <td style="" id="column8" valign="top"></td>
</tr>
<tr>
  <td style="" id="column1" valign="top"></td>
  <td style="" id="column2" valign="top"></td>
  <td style="" id="column3" valign="top"></td>
  <td style="" id="column4" valign="top"></td>
  <td style="" id="column5" valign="top" colspan="1" class="style8">ELEMENT 5</td>
  <td style="" id="column6" valign="top"></td>
  <td style="" id="column7" valign="top"></td>
  <td style="" id="column8" valign="top"></td>
</tr>

My code to scrape the above HTML is below. The issue I have is with finding element 5. I believe it's because that falls outside the /tbody. However, I can't figure out how to access that via $dom->query. You can see my attempted path below, but it is empty.

<?php

$data = array();
foreach ($dom->query('//tbody[@style="page-break-inside: avoid"]') as $key => $tr) {

  $value = $dom->query('tr[1]/td[@id="column2"]', $tr);
  $value = isset($value->item(0)->nodeValue) ? trim($value->item(0)->nodeValue) : "";
  if ($value != "") {

  
    if (!is_numeric($value[0])) {
      $d = array();

      $element_1 = $dom->query('tr[1]/td[@id="column3"]', $tr);
      $element_2 = isset($value2->item(0)->nodeValue) ? trim($value2->item(0)->nodeValue) : "";
      
      //saves elements 1 and two
      $d[] = $element_1 . $element_2;

      //saves element 3
      $element_3 = $dom->query('tr[1]/td[@id="column4"]/a', $tr);
      $element_3 = isset($element_3->item(0)->nodeValue) ? trim($element_3->item(0)->nodeValue) : "";
      $d["element3"] = $element_3;

      //saves element 4
      $element_4 = $dom->query('tr[1]/td[@id="column4"]/a/@href', $tr);
      $element_4 = isset($element_4->item(0)->nodeValue) ? "http://miamibeach.novusagenda.com/agendapublic/" . trim($element_4->item(0)->nodeValue) : "";
      $d["element 4"] = $element_4;

      //saves element 5
      $element_5 = $dom->query('tr[5]/td[@id="column5"]', $tr);
      $element_5 = isset($element_5->item(0)->nodeValue) ? trim($element_5->item(0)->nodeValue) : "";
      $d["element 5"] = $element_5;           

      //enters all the $d array data into the $data array
      $data[] = $d;
    }
  }
}
2 Answers

To get all TR from your html source you can try the following XPath query

$xpath = 
  '//tbody[@style="page-break-inside: avoid"]/tr|' .
  '//tbody[@style="page-break-inside: avoid"]/following-sibling::tr';

$rows = $dom->query($xpath);

// ...

//saves element 5
$element_5 = $dom->query('td[@id="column5"]', $rows[4]);
$d["element 5"] = isset($element_5[0]) ? trim($element_5[0]->nodeValue) : '';

which is equivalent to the css selector

tbody[style="page-break-inside: avoid"] > tr,
tbody[style="page-break-inside: avoid"] ~ tr

Without getting into the details of the rest of the code, to access - for example - the text node of the 5th <td> child node of the 5th <tr> node, the following

$element_5 = $dom->query('(//tr)[5]/td[@id="column5"]/text()');
echo $element_5[0]->nodeValue;

should output

ELEMENT 5
Related