dougang5088
2017-12-16 17:48
浏览 29
已采纳

使用DOMDocument在现有HTML表中创建新列

Attempting to create a new column within an existing table using DOMDocument and DOMXpath

$doc = new DOMDocument();
$doc->loadHTMLFile("example.html");

Here is how the table located in example.html is structured:

<table id="transactions" class="table">
    <thead>
        <tr>
            <th class="image"></th>
            <th class="title"><span>Title</span></th>
        </tr>
    </thead>
    <tbody>
        <tr id="tbody-tr">
            <td class="image">
                <img src="http://www.example.com/image.jpg">
            </td>
            <td class="title">Title
            </td>
            <td class="date">12/16/2017
            </td>
        </tr>
        <tr id="tbody-tr">
            <td class="image">
                <img src="http://www.example.com/image.jpg">
            </td>
            <td class="title">Title
            </td>
            <td class="date">12/16/2017
            </td>
        </tr>
    </tbody>
</table>

In this case, the xpath query for the table would be

$table =  $xpath->query('//*[@id="transactions"]');

For the <tr id="tbody-tr"> element

$tr = $xpath->query('/*[@id="tbody-tr"]');

And for the <td> row elements -- /td[1] /td[2] /td[3]

$td = $xpath->query('//*[@id="tbody-tr"]/td[3]');

I'm trying to create an additional column (<td class="example"></td>) in between <td class="title"> and <td class="date"> for all instances of <tr id="tbody-tr"> (there are about 50, but minified for the sake of the question).

I'm new to DOMDocument and HTML Parsing Manipulation, and am having a hell of a time trying to figure out how to do this.

I'm assuming I'll either have to loop it using my xpath->query, something like

foreach ($ttrows as $row) {
    $td = $doc->createElement('td');
    $parent = $row->parentNode;
    $parent->appendChild($row);
    $td->setAttribute('class','example');
}

or use DOMDocuments getElementById or something similar.

foreach ($table = $doc->getElementById('tbody-tr') as $table) {
    $td = $doc->createElement('td');
    $td->setAttribute('class', 'example');
    $td->appendChild($table);
    $table->insertBefore($td, $table);
}

As I said, I am new to DOMDocument, so both of those examples do practically nothing.. but I think I am heading in the right direction (I hope).

The table, I believe, is fairly well structured to do something like this in DOMDocument. Can someone please shed some light on this, my trials and errors are leaving me with little result.

Solution:

foreach ($td as $row) {
    $td = $doc->createElement('td', 'text to be inserted');
    $td->setAttribute('class','example');
    $row->parentNode->insertBefore($td, $row);
}

Note above that

$td = $xpath->query('//*[@id="tbody-tr"]/td[3]');

is the third <td> class date.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongpuchao1680 2017-12-16 18:21
    已采纳

    Remember you cant/shouldnt have multiple ids on the same page.

    Then just use $tr->insertBefore($td, $tr->childNodes->item(3));

    Which means, current node insert new dom node before 3rd td.

    <?php
    foreach ($doc->getElementsByTagName('tr') as $tr) {
        $td = $doc->createElement('td');
        $td->setAttribute('class', 'example');
    
        $tr->insertBefore($td, $tr->childNodes->item(3));
    }
    

    https://3v4l.org/TthE7

    Also something to think about is to add the thead > th or it will break the look of table.

    foreach ($doc->getElementsByTagName('tr') as $tr) {
    
        // insert into thead > th
        if ($tr->childNodes->item(0)->nodeName == 'th') {
            $th = $doc->createElement('th');
            $th->setAttribute('class', 'example');
            $th->nodeValue = 'Example';
            $tr->insertBefore($th, $tr->childNodes->item(3));
        } 
        // insert into body > td
        else {
            $td = $doc->createElement('td');
            $td->setAttribute('class', 'example');
    
            $tr->insertBefore($td, $tr->childNodes->item(3));
        }
    }
    

    https://3v4l.org/1sj7s

    点赞 打赏 评论

相关推荐 更多相似问题