Autor Zpráva
lionel messi
Profil
Zdravím,

rád by som si vytvoril jednoduchý HTML parser, ktorý mi automaticky zmení poradie stĺpcov v tabuľke. Momentálne mám skript, ktorý funguje správne, iba ak bunka tabuľky neobsahuje žiadny iný element. Kód nižšie vymieňa druhý a tretí stĺpec tabuľky.

Kvalita kódu je otrasná, píšem to z rýchlika, ide o princíp:
$html = new DOMDocument;
$html->loadHTML($tabulka);
$tabulky = $html->getElementsByTagName("table");
foreach ($tabulky as $table) {
    $riadky = $table->getElementsByTagName("tr");
    foreach ($riadky as $riadok) {
        $bunky = $riadok->getElementsByTagName("td");
        $hodnota = $bunky->item(1)->nodeValue;
        $bunky->item(1)->textContent = $bunky->item(2)->nodeValue;
        $bunky->item(2)->textContent = $hodnota;
    }
}
echo $html->saveHTML();

Problém nastáva, ak bunka tabuľky obsahuje ľubovoľný iný element, pretože v tom prípade iba vezme jeho hodnotu. Hľadám však riešenie, ktoré nielenže zachová všetky vnorené elementy (počet týchto vnorení môže byť ľubovoľný), ale zároveň aj ich polohu v rámci bunky (nevyhovuje mi, ak by sa vnorené elementy pridávali automaticky na začiatok, resp. koniec bunky).

Vopred ďakujem za každé nasmerovanie.
Tomášeek
Profil
lionel messi:
Neměl bys někde ukázku včetně zdrojové tabulky, kde bych si mohl některé věci dumpnout (DOMDocument z hlavy neznám)?

Pokud nodeValue vrací jen první element buňky (což se mi zdá divné), asi budeš muset pracovat s celou kolekcí potomků, ti by měli být v childNodes (možná rekurzivně, pokud bude zanoření více, těžko říct bez potřebné znalosti a dumpnutí).
lionel messi
Profil
Tomášeek:
Neměl bys někde ukázku včetně zdrojové tabulky, kde bych si mohl některé věci dumpnout (DOMDocument z hlavy neznám)?

Ďakujem za ochotu, pokiaľ ide o jednotlivé zanorenia, vyzerá tabuľka takto:

<table>
    <tr>
                                        <td class="druh"><i class="fa fa-o" aria-hidden="true"></i>Výr skalný</td>
                                        <td class="latinsky">Bubo bubo</td>
                                        <td class="potrava">Zajace, bažanty, hraboše, myši</td>
                                    </tr>                                
    <tr>
                                        <td class="druh"><i class="fa fa-o" aria-hidden="true"></i>Ropucha bradavičnatá</td>
                                        <td class="latinsky">Bufo bufo</td>
                                        <td class="potrava">Mäkkýše, pavúky, myši</td>
                                    </tr>
                                    <tr>
                                        <td class="druh"><i class="fa fa-o" aria-hidden="true"></i>Kobra kráľovská</td>
                                        <td class="latinsky">Naja naja</td>
                                        <td class="potrava">
                                            Môj jedálniček je vskutku široký
                                            <a href="#viac-1" class="collapsed" data-toggle="collapse" aria-expanded="false">Viac...</a>
                                            <div id="viac-1" class="collapse" aria-expanded="false" style="height: 0px;">
                                                Rada si pochutím na hadoch, pytónoch, jaštericiach, žabách, hlodavcoch, vtákoch, či pavúkoch,
                                                nepohrdnem však ani zaklínačom hadov.
                                            </div>
                                        </td>
                                    </tr>
</table>

A povedzme, že chcem v PHP vymeniť prvý stĺpec (slovenský názov živočícha) s posledným (potravou).
Kajman
Profil
Pokud tabulka neobsahuje rowspany a colspany, tak můžete přehodit celé buňky řádku. Něco jako
$html = new DOMDocument;
$html->loadHTML($tabulka);
$riadky = $html->getElementsByTagName("tr");
foreach ($riadky as $riadok) {
    $bunky=[];//td|th
    foreach($riadok->childNodes as $nod) {
        if($nod->nodeType==XML_ELEMENT_NODE) {
            $bunky[]=$nod;
        }
    }
    if(count($bunky)>=3) {
        $riadok->insertBefore($bunky[2],$bunky[0]);//3. na zacatek
        $riadok->insertBefore($bunky[0]);//puvodni 1. na konec
    }
}

echo $html->saveHTML();
lionel messi
Profil
Kajman:

Ďakujem, takéto riešenie mi plne vyhovuje.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0