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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么