Search code examples
phphtmlxpathdomdocument

Change HTML using Xpath and DomDocument?


i have Following HTML src :

$content = "<table>

<tr>
  <td>AAA</td>
  <td>30,40 €</td>
  <td>41,10 €</td>
</tr>
<tr>
  <td>BBB</td>
  <td>30,40 €</td>
  <td>41,10 €</td>
</tr>
<tr>
  <td>CCC</td>
  <td>30,40 €</td>
  <td>41,10 €</td>
</tr>
</table>";

I want to update all 1st <td> in <tr>, to add a class on <td> :

<table>

    <tr>
      <td class='first'>AAA</td>
      <td>30,40 €</td>
      <td>41,10 €</td>
    </tr>
    <tr>
      <td class='first'>BBB</td>
      <td>30,40 €</td>
      <td>41,10 €</td>
    </tr>
    <tr>
      <td class='first'>CCC</td>
      <td>30,40 €</td>
      <td>41,10 €</td>
    </tr>
    </table>

I'm able to get the elements i want with this :

$dom = new DOMDocument();
@$dom->loadHTML($table);
$xpath = new DOMXPath($content);

foreach($xpath->query('//td[1]') as $td){
    echo $td->nodeValue."\n\n";

}

However, i dont know how change the content to add my class.

You have ideas ?


Solution

  • You can just use setAttribute to add a class to your first td elements:

    $doc = new DOMDocument();
    $doc->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    $xpath = new DOMXPath($doc);
    foreach ($xpath->query('//td[1]') as $td) {
        $td->setAttribute('class', 'first');
    }
    echo $doc->saveHTML();
    

    Note that you need to convert your utf-8 as DOMDocument doesn't understand it well. Also DOMXPath should refer to the DOMDocument, not the original HTML.

    Output

    <table>
     <tr>
      <td class="first">AAA</td>
      <td>30,40 &euro;</td>
      <td>41,10 &euro;</td>
     </tr>
     <tr>
      <td class="first">BBB</td>
      <td>30,40 &euro;</td>
      <td>41,10 &euro;</td>
     </tr>
     <tr>
      <td class="first">CCC</td>
      <td>30,40 &euro;</td>
      <td>41,10 &euro;</td>
     </tr> 
    </table>
    

    Demo on 3v4l.org