5. diel - Práca so súbormi XML v PHP - Čítanie
V predchádzajúcej lekcii, Práca so súbormi XML v PHP , sme sa zoznámili s prácou so súbormi vo formáte XML. Prebrali sme použitie tried XMLWriter, XMLReader a SimpleXML.
Dnes sa opäť inšpirujeme článkom Čítanie XML SAXom v C# a napíšeme si podobnú aplikáciu v jazyku PHP. Použijeme XML dáta, ktoré sme si vygenerovali v lekcii práce so súbormi XML v PHP - Zápis:
<?xml version="1.0" encoding="UTF-8"?> <uzivatele> <uzivatel vek="22"> <jmeno>Pavel Slavík</jmeno> <registrovan>21.3.2000</registrovan> </uzivatel> <uzivatel vek="31"> <jmeno>Jan Novák</jmeno> <registrovan>30.10.2012</registrovan> </uzivatel> <uzivatel vek="16"> <jmeno>Tomáš Marný</jmeno> <registrovan>12.1.2011</registrovan> </uzivatel> </uzivatele>
Tento súbor si uložíme do projektovej zložky.
Čítanie XML metódou SAX
– trieda XMLReader
Tentokrát je úloha oveľa ťažšia, než generovanie XML metódou SAX. Musíme totiž čítať jednotlivé tokeny a ich postupnosťou riadiť ukladanie dát. Záujemcom odporúčam metódu použiť iba v špecifických prípadoch, napríklad keď z obrovského XML súboru potrebujú len vybrať niektoré dáta. V ostatných prípadoch je výhodnejšie použiť metódu DOM.
Trieda Uzivatel
Najprv si definujeme triedy, ktoré budú v zložke tridy/
. Ako
prvú si definujeme triedu Uzivatel
:
class Uzivatel { private string $jmeno; private int $vek; private string $registrovan; public function __construct(XMLReader $data) { $this->vek = $data->getAttribute('vek'); while ($data->read()) { switch ($data->name) { case 'jmeno': $data->read(); $this->jmeno = $data->value; $data->read(); break; case 'registrovan': $data->read(); $this->registrovan = $data->value; $data->read(); break; // ďalšie elementy case '#text': break; default: return; } } } public function __toString(): string { return sprintf("%-20s %2d %10s", $this->jmeno, $this->vek, $this->registrovan); } }
Najkomplikovanejšia trieda dnes bude najskôr Uzivatel
. Najprv
ju prečítame atribút vek
elementu uzivatel
. Potom
ju prečítame aj obsah elementov jmeno
a registrovan
.
Pokiaľ parser (cyklus while()
) narazí na neznámy element, je
konštruktor ukončený. Pseudoelement #text
obsahuje biele znaky,
ktoré sú medzi elementmi zdrojového XML a ktorých sa potrebujeme zbaviť.
Prečítané atribúty XML si uložíme do príslušných atribútov triedy.
Trieda Uzivatele
Druhá trieda bude Uzivatele
, ktorá bude reprezentovať zoznam
užívateľov:
class Uzivatele { private array $seznam = array(); public function __construct(XMLReader $data) { while ($data->read()) { switch ($data->name) { case 'uzivatel': if ($data->nodeType == XMLReader::ELEMENT) { $this->seznam[] = new Uzivatel($data); } break; case 'uzivatele': return; } } } public function __toString(): string { $uzivatele = array(); foreach ($this->seznam as $uzivatel) { $uzivatele[] = $uzivatel->__toString(); } return implode("\n", $uzivatele); } }
Súbor index.php
Nakoniec stačí súbor index.php
:
require('tridy/Uzivatel.php'); require('tridy/Uzivatele.php'); // prečítame súbor s XML dátami $data = new XMLReader(); // tu si prípadne upravte cestu k súboru XML $data->open('../data.xml'); // prejdeme elementy XML súboru a pretransformujeme ich do triedy Uzivatele while ($data->read()) { switch ($data->name) { case 'uzivatele': $uzivatele = new Uzivatele($data); break; } } // výstup si necháme vypísať do prehliadača pre kontrolu header("Content-Type: text/plain; charset=UTF-8"); echo($uzivatele . "\n");
Pozornejší programátori si všimli, že v konštrukcii switch
používame len 1× case
namiesto kratšieho zápisu
if
. Je tomu tak preto, že na čítanie používame metodiku
regulárneho automatu, pri ktorej je použitie switch
obvyklé. Pri
parsovaní zložitejšieho dokumentu určite oceníme jednoduchú
rozšíriteľnosť.
Výstup
Po spustení skriptu dostaneme nasledujúci výsledok:
Uvedený príklad nie je naprogramovaný úplne najčistejšie. Určite by sa našla kombinácia validných vstupných dát, ktorá by neprešla. Mala to byť len ukážka, že aj v PHP je možné použiť metódu SAX na čítanie dokumentov XML.
Čítanie XML triedou
SimpleXML
Hovorili sme o tom, že čítanie XML metódou SAX nie je na bežné
použitie vhodné. Teraz si ukážeme ten lepší spôsob pomocou triedy
SimpleXML
.
Trieda SimpleXML
je určená na jednoduchú konverziu dokumentu
XML do objektov v PHP. Na rozdiel od triedy XMLReader
však
dokument nečítame v cykle po jednotlivých elementoch, ale načítame ho celý
do objektovej štruktúry. To je veľmi výhodné, pretože najpomalší úkon
vykonáva štandardná knižnica, ktorá je na tento účel optimalizovaná.
Použijeme opäť rovnaké dáta:
<?xml version="1.0" encoding="UTF-8"?> <uzivatele> <uzivatel vek="22"> <jmeno>Pavel Slavík</jmeno> <registrovan>21.3.2000</registrovan> </uzivatel> <uzivatel vek="31"> <jmeno>Jan Novák</jmeno> <registrovan>30.10.2012</registrovan> </uzivatel> <uzivatel vek="16"> <jmeno>Tomáš Marný</jmeno> <registrovan>12.1.2011</registrovan> </uzivatel> </uzivatele>
Trieda Uzivatele
Tu nám oproti metóde SAX stačí vytvoriť iba jednu triedu
Uzivatele
:
class Uzivatele { private SimpleXMLElement $seznam; public function __construct(string $souborXML) { $this->seznam = new SimpleXMLElement($souborXML, null, true); } public function __toString(): string { $uzivatele = array(); foreach ($this->seznam as $uzivatel) { $uzivatele[] = sprintf("%-20s %2d %10s", $uzivatel->jmeno, $uzivatel['vek'], $uzivatel->registrovan); } return implode("\n", $uzivatele); } }
Súbor index.php
Skript vypisujúci údaje je veľmi krátky
require('tridy/Uzivatele.php'); // tu si prípadne upravte cestu k súboru XML $data = new Uzivatele('../data.xml'); header("Content-Type: text/plain; charset=UTF-8"); echo($data . "\n");
Podľa potreby môžeme samozrejme doplniť metódy na vyhľadanie užívateľa, overenie hesla a pod. Na náš účel postačí obyčajný výpis zoznamu užívateľov.
Výstup
Po spustení skriptu sa v prehliadači objaví:
Ako vidíme, čítanie dokumentu triedou SimpleXMLElement
je
oveľa jednoduchšie, než čítanie metódou SAX. Táto trieda je tiež asi
10× rýchlejšia ako XMLReader
a lepšie zdokumentovaná. Pre
spracovanie bežných dokumentov XML je preto oveľa výhodnejšie.
Kompletný kód všetkých príkladov z tejto lekcie nájdete ako vždy na stiahnutie dole pod článkom:-)
V ďalšej lekcii, Práca s archívmi ZIP v PHP , sa zoznámime s prácou s archívmi vo formáte
ZIP v PHP. Ukážeme si triedu ZipArchive
a jej najdôležitejšie
metódy.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 10x (5.35 kB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP