Search code examples
phpparsingmergedomdocumenttablecell

How to combine two table cells in the same table row?


How can I merge the date td/cell into the time td/cell?

I would like the table row to consist of 3 cells, the middle cell should read date time.

My Code:

$dom = new DOMDocument;
$dom->loadHTMLFile("test.html");
$dom->validateOnParse = true;
$xpath                = new DOMXPath($dom);
$table = $xpath->query("//*[@class='mytable']//tbody")->item(0);
$td = $table->getElementsbytagname("td");

test.html file contents:

<table class="mytable">
  <tbody><tr>
      <td>date</td>
      <td>td1</td>
      <td>time</td>
      <td>td2</td>
    </tr></tbody>
</table>

Desired result:

<table class="mytable">
  <tbody><tr>
      <td>td1</td>
      <td>date time</td>
      <td>td2</td>
    </tr></tbody>
</table>

Solution

  • Collect the tbody tr cells. Overwrite the 3rd occurring cell's text using the 1st occurring cell' text, then delete the first cell.

    Code (Demo)

    $html = <<<HTML
    <table class="mytable">
      <tbody><tr>
          <td>date</td>
          <td>td1</td>
          <td>time</td>
          <td>td2</td>
        </tr></tbody>
    </table>
    HTML;
    
    $dom = new DOMDocument;
    $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    $xpath = new DOMXPath($dom);
    foreach ($xpath->query("//table[@class='mytable']/tbody/tr") as $tr) {
        $tds = $tr->getElementsByTagName("td");
        $tds->item(2)->nodeValue = $tds->item(0)->nodeValue .
                                   ' ' . $tds->item(2)->nodeValue;
        $tr->removeChild($tds->item(0));
    }
    echo $dom->saveHTML();
    

    Output:

    <table class="mytable">
      <tbody><tr>
    
          <td>td1</td>
          <td>date time</td>
          <td>td2</td>
        </tr></tbody>
    </table>