Matthew Price
Matthew Price

Reputation: 41

PHP DOM HTML table manipulation

I'm trying to figure out why this piece of code isn't working. It takes HTML from another part of the code, takes the table out of it, creates another column and tries to move a td element to the row above in the newly created column.

The table imported:

+-------------------+-------------------+-------------------+
| Existing column1  | Existing column2   | Existing column3 |
+-------------------+-------------------+-------------------+
| A                 | B                 | C                 |
| D                 | E                 | F                 |
| G                                                         |
+-------------------+-------------------+-------------------+

I want to try and make it look like this:

+-------------------+-------------------+-------------------+-------------+
| Existing column1  | Existing column2  | Existing column3  | New column1 |
+-------------------+-------------------+-------------------+-------------+
| A                 | B                 | C                 |             |
| D                 | E                 | F                 | G           |
+-------------------+-------------------+-------------------+-------------+

So whenever a td element has the class text-info, it moves it up a tr and appends it to the last Comment column

My code so far:

$dom = new DOMDocument();//Loads DOM document
$dom->loadHTML($str);//Loads HTML from a previously set variable
$xpath = new DOMXPath($dom);
$tables = $xpath->query('//table[@class="behaviourtable table"]');//Get only table from HTML
$commsTable = '';
foreach ($tables as $table) {
    $commsTable .=  $dom->saveXML($table);
}

$commsHTML = new DOMDocument();
$commsHTML->loadHTML($commsTable);

$tr = $commsHTML->getElementsByTagName('tr');


$th = $commsHTML->createElement('th', 'Comment');
$tr->item(0)->appendChild($th);

$xpathcomms = new DOMXPath($commsHTML);
$comments = $xpathcomms->query('//td[@class="text-info"]');
if($comments->length > 0){
    echo "if running";
foreach($comments as $comment){
    $parent = $comment->parentNode;
$parent->appendChild($comment);
$commsHTML->saveXML($parent);
}

}


echo $commsHTML->saveHTML();

Upvotes: 2

Views: 1500

Answers (1)

Dekel
Dekel

Reputation: 62636

In your code you append the td to it's original parent node (which does nothing), while what you are actually wanna do is get the parent (tr), go to it's previous sibling (prev tr) and append the td to that tr:

foreach($comments as $comment){
    $parent = $comment->parentNode;
    $parent->previousSibling->appendChild($comment);
}

Here is a complete working example:

$str = <<<END
<table class="behaviourtable table">
    <tr>
        <th>Existing column1</th>
        <th>Existing column2</th>
        <th>Existing column3</th>
    </tr><tr>
        <td>A</td>
        <td>B</td>
        <td>C</td>
    </tr><tr>
        <td>D</td>
        <td>E</td>
        <td>F</td>
    </tr><tr>
        <td class="text-info">G</td>
    </tr>
</table>
END;

$dom = new DOMDocument();//Loads DOM document
$dom->loadHTML($str);//Loads HTML from a previously set variable
$xpath = new DOMXPath($dom);
$tables = $xpath->query('//table[@class="behaviourtable table"]');//Get only table from HTML
$commsTable = '';
foreach ($tables as $table) {
    $commsTable .=  $dom->saveXML($table);
}

$commsHTML = new DOMDocument();
$commsHTML->loadHTML($commsTable);

$tr = $commsHTML->getElementsByTagName('tr');


$th = $commsHTML->createElement('th', 'Comment');
$tr->item(0)->appendChild($th);

$xpathcomms = new DOMXPath($commsHTML);
$comments = $xpathcomms->query('//td[@class="text-info"]');
if($comments->length > 0){
    foreach($comments as $comment){
        $parent = $comment->parentNode;
        $parent->previousSibling->appendChild($comment);
    }
}

echo $commsHTML->saveHTML();

Check this working example:
https://3v4l.org/FZkNE

Upvotes: 2

Related Questions