PHP: HTML fájl feldolgozása és manipulálása

Már az elején lelövöm a poént: Ha a PHP saját XML DOM parserét használod, biztosan kevesebb hajad marad a nap végére. A SimpleXML sajnos kevés ehhez, de a csodafegyver itt van: http://simplehtmldom.sourceforge.net/manual.htm .

Történt ugyanis, hogy HTML sablon alaján kell PDF-et generálnom. A sablonban táblázatok vannak formázva ( na itt bukott el a PHP XML DOM osztály, mert piszok kacifántos vele xHTML-t manipulálni ), aminek a formázását meg kellene őrizni, hisz’ ez adja majd a PDF stílusát. De vannak mezők, amik helyére be kell helyettesíteni a megfelelő értékeket.

A sablon valami ilyesmi:

<table id="TableParts" cellspacing="0" cellpadding="4">
 <thead id="TablePartsHeader">
 <tr style="background-color: black; color: white;">
   <th align="center">[TITLE_PART_NUMBER]</th>
   <th align="center">[TITLE_PART_NAME_AND_SUPPLIER]</th>
   <th align="center">[TITLE_PART_TYPE]</th>
   <th align="center">[TITLE_QUANTITY]</th>
   <th align="center">[TITLE_MEASUREMENT_UNIT]</th>
   <th align="center">[TITLE_BASE_PRICE_WO_VAT]</th>
   <th align="center">[TITLE_VAT_PERCENT]</th>
   <th align="center">[TITLE_BASE_PRICE_W_VAT]</th>
 </tr>
 </thead>
   <tbody id="TablePartsBody">
   <tr data-bgcolor1="white" data-bgcolor2="silver">
   <td align="right">[PART_NO]</td>
   <td align="right">[PART_NAME]<br />[PART_SUPL_NAME] ([PART_SUPL_CODE])</td>
   <td align="right">[PART_TYPE]</td>
   <td align="right">[PART_QUANTITY]</td>
   <td align="right">[PART_MEASUREMENT_UNIT]</td>
   <td align="right">[PART_BASE_PRICE_WO_VAT]</td>
   <td align="right">[PART_VAT_PERCENT]%</td>
   <td align="right">[PART_BASE_PRICE_W_VAT]</td>
 </tr>
 </tbody>
</table>
<table id="TablePackages" cellspacing="0" cellpadding="4" nobr="true">
   <thead id="TablePackagessHeader">
   <tr style="background-color: black; color: white;">
   <th align="center">[TITLE_PACKAGE_CODE]</th>
   <th align="center">[TITLE_DESCRIPTION]</th>
   <th align="center">[TITLE_QUANTITY]</th>
   <th align="center">[TITLE_PART_NUMBER]</th>
   <th align="center">[TITLE_PART_SUPPLIER]</th>
   <th align="center">[TITLE_PART_QTY]</th>
   <th align="center">[TITLE_PACKAGE_PRICE_WO_VAT]</th>
 </tr>
 </thead>
   <tbody id="TablePackagesBody">
   <tr data-bgcolor1="white" data-bgcolor2="silver">
   <td align="right">[PACKAGE_CODE]</td>
   <td align="right">[PACKAGE_DESCRIPTION]</td>
   <td align="right">[PACKAGE_QUANTITY]</td>
   <td align="right">[PART_NUMBER]</td>
   <td align="right">[PART_SUPPLIER]</td>
   <td align="right">[PART_QTY]</td>
   <td align="right">[PACKAGE_PRICE_WO_VAT]</td>
 </tr>
 </tbody>
</table>

Először is betöltjük a tartalmat:

$htmldom = new simple_html_dom();
$htmldom->load($content); // URL-ről és fájlból is lehet, RTFM

A táblázat fejlécek cserélgetése:

$table_headers = $htmldom->find('th');

foreach ( $table_headers as $th ) {
  // a találat HTML kódja az innertext-ben van, a keresett tag-gel együtt, pedig az outertext-ben
  $innertext = $th->innertext; 
  $th->innertext = str_replace( array_keys($replace), array_values($replace), $innertext );
}

A táblázat sorok cserélgetése:

foreach ($cartData->Parts as $Part) {

  $e = $htmldom->getElementById("TablePartsBody")->getElementByTagName('tr');
  // minden 2. sor háttérszínezése, ha nincs data-bgcolor1, akkor legyen csak fehér
  $tr_bgcolor1 = ($e->getAttribute('data-bgcolor1')) ? $e->getAttribute('data-bgcolor1') : 'white'; 
  $tr_bgcolor2 = ($e->getAttribute('data-bgcolor2')) ? $e->getAttribute('data-bgcolor2') : 'silver';

  // hogy jobban olvasható elgyen a táblázat
  $tr.= (++$i%2==1) ? '<tr style="background-color: '.$tr_bgcolor1.';">' : '<tr style="background-color: '.$tr_bgcolor2.';">'; 

    foreach ( $htmldom->getElementById("TablePartsBody")->find('td') as $tkey => $td ) {
      // pl. $replace_parts = array( '[PART_NO]' => $Part->PartNo, 'PART_SUPL' => $Part->Supl );
      $tr.= str_replace( array_keys( $replace_parts ), array_values( $replace_parts ), $td->outertext ); 
    }

  $tr.='</tr>'.PHP_EOL;
}

$htmldom->getElementById("TablePartsBody")->innertext = ''; // biztos ami tuti, a sablon törlése
$htmldom->getElementById("TablePartsBody")->innertext = $tr; // bekerülnek a táblázat sorok

$htmldom->getElementById("TablePartsBody")->makeup(); // Újra XML objektum lesz az osztály számára

A kész HTML pedig így érhető el:

echo $htmldom->save();

Jó mi? 🙂