首页 > 解决方案 > 从 DOM 表中删除子节点仅删除备用子节点

问题描述

我正在使用 PHP,并且我有一个包含字符串的 HTML 字符串。我需要删除表的所有行(实际上,会有一些逻辑来检查是否删除该行,但现在我正在删除所有行)。

我正在尝试从表中删除所有行,但只有备用行被删除。

$html_string = <<<HTML
<div class="my-table-div">
   <div class="clear"></div>
   <div class="table-wrap">
      <table id="my-table" class="my-class">
         <thead>
            <tr>
               <th class="manage-column" scope="col">Col1</th>
               <th class="manage-column" scope="col">Col2</th>
               <th class="manage-column" scope="col">Col3</th>
               <th class="manage-column" scope="col">Col4</th>
               <th class="manage-column" scope="col">Col5;</th>
            </tr>
         </thead>
         <tbody>
            <tr>
               <td></td>
               <td>Item 1</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
            <tr>
               <td></td>
               <td>Item 2</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
            <tr>
               <td></td>
               <td>Item 3</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
            <tr>
               <td></td>
               <td>Item 4</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
         </tbody>
      </table>
   </div>
</div>
HTML

$doc = new DOMDocument();
$doc->loadHTML($html_string);
$table = $doc->getElementsByTagName('table')[0];
$trs = $table->getElementsByTagName('tr');
for( $x=1; $x<count($trs); $x++ ) {
      $trs[$x]->parentNode->removeChild($trs[$x]);
}

//var_dump($doc->saveHTML()); // to check output of the above code

执行上述操作后的实际结果:

Col1    Col2    Col3    Col4    Col5
        Item 2          
        Item 4

预期结果:

Col1    Col2    Col3    Col4    Col5

标签: phphtmldom

解决方案


你的问题是关于理解这部分代码

$trs[$x]->parentNode->removeChild($trs[$x]);

当您以这种方式删除元素时,该元素将从中删除$trs,然后在索引中重新索引,例如查看和本示例

elements
    1 -> sub element 1
    2 -> sub element 2
    3 -> sub element 3

当您删除第一个时,它将是这样的

elements
    1 -> sub element 2
    2 -> sub element 3

现在您再次需要删除索引为 1 的元素,
因此您应该将此代码更改为这样的

$trs[1]->parentNode->removeChild($trs[1]);

你的最终代码将是这样的

$html_string = '
<div class="my-table-div">
   <div class="clear"></div>
   <div class="table-wrap">
      <table id="my-table" class="my-class">
         <thead>
            <tr>
               <th class="manage-column" scope="col">Col1</th>
               <th class="manage-column" scope="col">Col2</th>
               <th class="manage-column" scope="col">Col3</th>
               <th class="manage-column" scope="col">Col4</th>
               <th class="manage-column" scope="col">Col5;</th>
            </tr>
         </thead>
         <tbody>
            <tr>
               <td></td>
               <td>Item 1</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
            <tr>
               <td></td>
               <td>Item 2</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
            <tr>
               <td></td>
               <td>Item 3</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
            <tr>
               <td></td>
               <td>Item 4</td>
               <td></td>
               <td></td>
               <td></td>
            </tr>
         </tbody>
      </table>
   </div>
</div>';

$doc = new DOMDocument();
$doc->loadHTML($html_string);
$table = $doc->getElementsByTagName('table')[0];
$trs = $table->getElementsByTagName('tr');
$trCount = count($trs) - 1;
for( $x=0; $x < $trCount; $x++ ) {
      $trs[1]->parentNode->removeChild($trs[1]);
}

print_r($doc->saveHTML());

推荐阅读