Dnes využijeme znalosti z minulých dílů a předvedeme si, co kombinace XML a PHP dokáže. Sestrojíme si parser, který bude umět zapsat data do pole a z těchto dat pak vytvoří tabulku. Parser se bude skládat ze dvou částí – čtečky XML souboru a skriptu, který předá data ve formě tabulky na obrazovku. Celý skript lze použít pro zobrazování ceníků či různých seznamů.

Budeme předpokládat, že zdrojový XML soubor vypadá nějak takto, jednoduchými úpravami ve skriptu ho však můžeme přizpůsobit i pro jiné typy souborů.

V první části bude samotný parser. Před jeho spuštěním zaregistrujeme obsluhu tagů a znakových dat. Pokaždé, když narazí parser na počáteční tag elementu symbolizujícího jeden řádek tabulky (<radek>), přičte k proměnné $radek jedničku. Když parser narazí na počáteční tag elementu symbolizujícího buňku tabulky (<sloupec>), přičte k proměnné $sloupec jedničku. Jakmile narazí parser na obsah elementu, začne ho vpisovat do $pole[$radek][$sloupec]. Je pravděpodobné, že parser narazí na několik „sloupců“ v jednom řádku. Pokaždé se při počátečním tagu pro buňku přidá nový sloupec, do kterého se obsah elementu vypíše. Až skončí řádek (tj. parser narazí na </radek>), nastaví se hodnota $sloupec zpátky na nulu.

Nejprve vytvoříme nový parser $parser a nastavíme příslušné proměnné na výchozí hodnotu:

$jmenosouboru=“datad.xml“;
$pole=array();
$radek=0;
$sloupec=0;
$parser=(xml_parser_create());

Dále zaregistrujeme obsluhu elementů:

function obsluhapocatecnihotagu($parser, $nazev, $atributy) {
global $radek, $sloupec, $pole;
if(eregi($nazev, „radek“)) {$radek=$radek+1;}
if(eregi($nazev, „sloupec“)) {$sloupec=$sloupec+1;}
}
function obsluhakoncovehotagu($parser, $nazev) {
global $radek, $sloupec, $pole;
if(eregi($nazev, „radek“)) {$sloupec=0;}
}
xml_set_element_handler($parser, „obsluhapocatecnihotagu“, „obsluhakoncovehotagu“);

Obsluha počátečního tagu, pokud je jeho název radek, přičte k $radek jedničku. Pokud je název tagu sloupec, přidá k proměnné $sloupec jedničku. Obsluha koncového tagu, pokud je jeho název radek, vynuluje proměnnou sloupec, aby v dalším řádku šly sloupce zase od nuly. Nesmíme zapomenout na nastavování proměnných $pole, $radek a $sloupec jako globálních, protože jinak by se jejich hodnota po dokončení funkce vždy vynulovala.

Pak musíme zaregistrovat obsluhu textových znaků:

function znaky($parser, $data) {
global $radek, $sloupec, $pole;
$pole[$radek][$sloupec] .= $data;
}
xml_set_character_data_handler($parser, „znaky“);

Do pole se postupně přidává znak po znaku celý obsah buňky budoucí tabulky. Opět nesmíme zapomenout nastavit globální proměnné.

A nyní přichází spuštění samotného parseru:

if(!($soubor=fopen($jmenosouboru, „r“))) {
die(„Nelze otevřít soubor „.$jmenosouboru.“!“);
} else {
while ($d = fread($soubor, 4096)) {
 if(!xml_parse($parser, $d, feof($soubor))) {
  die(„<script language=\“JavaScript\“>
  window.alert(‚Chyba XML v souboru „.$jmenosouboru.“ na řádku „.xml_get_current_line_number($parser).“.\\n\\nKód chyby: „.xml_get_error_code($parser).“‚);
  </script>“);
 }
}
}

Pokud nepůjde otevřít soubor, zastaví se provádění celého skriptu a zobrazí se chybová hláška. Pokud při čtení narazí parser na chybu v XML, taktéž se ukončí provádění celého skriptu a zobrazí se JavaScript upozorňující na chybu.

Nyní přichází druhá, podstatně kratší část skriptu – zobrazení tabulky.

echo(„<table>“);
for($cr=1;$cr<=Count($pole);$cr++) {
echo(„<tr>“);
for($cs=1;$cs<=Count($pole[$cr]);$cs++) {
echo(„<td>“);
echo($pole[$cr][$cs]);
echo(„</td>“);
}
echo(„</tr>“);
}
echo(„</table>“);

Princip je podobný, jako čtení ze souboru, jen data proudí z pole do zdrojového kódu. Postupně se vypisují všechny řádky a všechny sloupce tabulky. Řešení zápisu do pole a následné zobrazení má tu výhodu, že můžeme jednoduše prohodit řádky a sloupce (což by při přímém vypisování nešlo) a s polem se dá dělat spousta dalších užitečných věcí (hledání, matematické operace a podobně).

Jednoduchou úpravou zobrazovací části pak můžeme například zvýraznit první řádek a první sloupec tabulky:

echo(„<table>“);
for($cr=1;$cr<=Count($pole);$cr++) {
echo(„<tr>“);
for($cs=1;$cs<=Count($pole[$cr]);$cs++) {
echo(„<td>“);
if($cs==1 || $cr==1) echo(„<strong>“);
echo($pole[$cr][$cs]);
if($cs==1 || $cr==1) echo(„</strong>“);
echo(„</td>“);
}
echo(„</tr>“);
}
echo(„</table>“);

Zdrojové soubory si můžete stáhnout a podívat se na první a druhou ukázku.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět