Vytvoření parseru a analýza dokumentu XML
Vytvoření parseru XML není v PHP problém. V tomto článku jej nejen vytvořím, ale na jednoduchém souboru XML i prakticky vysvětlím jeho funkčnost.
Soubor knihovna.xml
Jako analyzovaný dokument XML použiji ukázkový soubor knihovna.xml, který kromě elementů s příslušnými atributy obsahuje i další typické prvky jazyka XML: tzv. prolog, tj. XML deklaraci a deklaraci typu dokumentu, určení kódóvání, deklaraci entit a notace, dále instrukci pro zpracování, tedy kód určený ke zpracování jiným programem, komentáře, interní i externí textovou entitu a konečně i externí binární entitu pro vložení obrázku.
|
Systémové funkce PHP pro práci s XML
Nejdříve vám představím potřebné systémové funkce PHP 4 pro práci s XML:
xml_parser_create( )
Vytvoří parser XML. V jednom skriptu PHP lze vytvořit více parserů – mohu tak zpracovávat více dokumentů XML. Přiřadím-li tuto funkci např. proměnné $parser, získám parser XML pod jménem $parser.
xml_parser_free(jméno parseru)
Uvolňuje parser XML vytvořený předešlou funkcí. Všechny parsery vytvořené skriptem PHP by měly být uvolněny po přečtení celého dokumentu XML, nebo když při čtení dojde k chybě.
xml_get_current_line_number(jméno parseru), xml_get_current_column_number(jméno parseru)
Vrací číslo aktuálního řádku, resp. sloupce, který parser právě zpracovává. Tyto funkce mají význam pro ošetření chyb při analýze dokumentu XML – s jejich pomocí mohu chybu přesně lokalizovat.
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false)
Tuto funkci bych musel použít (v přesném znění s uvedenými parametry), pokud bych chtěl názvy elementů vypisovat malými písmeny. Implicitně se názvy elementů vypisují písmeny velkými.
xml_set_element_handler($parser, „startElementHandler“, „endElementHandler“)
Registruje obslužné funkce pro obsluhu počátečních a koncových elementů dokumentu XML. Nazval jsem si je „startElementHandler“ a „endElementHandler“. Parametr $parser určuje jméno parseru XML, kterému se příslušné obslužné funkce zaregistrují. Tento parametr používají i následující systémové funkce a nebudu se k němu tedy již vracet.
xml_set_character_data_handler($parser, „cdataHandler“)
Registruje obslužnou funkci pro čtení znakových dat dokumentu XML, kterou jsem si nazval „cdataHandler“.
xml_set_processing_instruction_handler($parser, „jinyProgram“)
Registruje obslužnou funkci k instrukcím pro zpracování, kterou jsem si nazval „jinyProgram“. Tato funkce bude mít na starosti správnou interpretaci kódu PHP vloženého do analyzovaného souboru knihovna.xml.
xml_set_external_entity_ref_handler($parser, „externiEntita“)
Registruje obslužnou funkci odkazu externí textové entity, kterou jsem si nazval „externiEntita“.
xml_set_notation_decl_handler($parser, „notace“)
Registruje obslužnou funkci deklarace notace, kterou jsem si nazval „notace“.
xml_set_unparsed_entity_decl_handler($parser, „neanalyzEntita“)
Registruje obslužnou funkci deklarace neanalyzované entity, kterou jsem si nazval „neanalyzEntita“. Tato funkce bude mít na starosti správnou interpretaci obrázku vloženého do souboru knihovna.xml
xml_set_default_handler($parser, „nedefinovano“)
Registruje obslužnou funkci, která je volána pokaždé, když parser narazí na uzel dokumentu XML, který není ošetřen žádnou z předešlých funkcí. Tuto obslužnou funkci jsem si nazval „nedefinovano“ a bude mít na starosti správnou interpretaci celého prologu a vložených komentářů.
xml_parse($parser, $data, $posledni)
Stará se o vlastní analýzu – volá zaregistrované funkce, jakmile narazí na příslušné uzly v dokumentu. Parametr $data určuje obsah dokumentu XML a parametr $posledni určuje konec vstupních dat. Není tedy nutné procházet celý obsah souboru XML najednou.
Obslužné funkce
Obslužné funkce jsou již poněkud zábavnější – zde si každý znalý jazyka PHP může nadefinovat výstup uzlů analyzovaného dokumentu XML do kódu HTML. Tento výstup je zcela modifikovatelný – představte si jednotlivé uzly dokumentu XML jako proměnné, se kterými můžete volně pracovat. V PHP není potom problém vytvořit například aplikaci, která by v souboru knihovna.xml dokázala vyhledávat knížky podle autorů, názvů nebo počtu stran a vyhledané knížky zobrazit do libovolné tabulky viditelné nejen v Exploreru, ale i třeba v Netscapu. Abych však princip obslužných funkcí ilustroval jednodušeji, použiji je pouze k vytvoření krátkého skriptu, který přečte a přehledně zobrazí všechny informace obsažené v souboru knihovna.xml. Výsledek v kódu html si můžete prohlédnout zde.
Definice obslužných funkcí
startElementHandler($parser, $name, $attribs)
K zavolání této mnou definované funkce dojde, když parser najde otevírací značku elementu v dokumentu. Parametr $parser identifikuje parser, který tuto funkci volá. Použiji-li tedy k vytvoření parseru například proměnnou $parser, musím i tento parametr nazvat $parser. Parametru $name je přiřazen název elementu. Parametr $attribs je asociativní pole. Jeho jednotlivé indexy odpovídají názvům atributů a odpovídající prvky jejich hodnotám.
|
endElementHandler($parser, $namekon)
K zavolání této mnou definované funkce dojde, když parser najde koncovou značku elementu v dokumentu. Parametr $parser identifikuje parser, který tuto funkci volá. Parametru $namekon je přiřazen název elementu.
|
cdataHandler($parser, $data)
K zavolání této mnou definované funkce dojde, když parser najde jakýkoli obsah dokumentu bez značek. Parametr $parser identifikuje parser, který tuto funkci volá. Parametru $data jsou přiřazena znaková data dokumentu XML. Parser data vrací přesně v jejich podobě – neodstraňuje mezery.
|
jinyProgram($parser, $cil, $data)
K zavolání této mnou definované funkce dojde, když parser najde v dokumentu XML instrukce pro jiný program. Parametr $parser identifikuje parser, který tuto funkci volá. Parametru $cil je přiřazeno jméno programu, který má instrukce zpracovat. Parametru $data jsou předány instrukce. Pokud tedy např. parser $parser narazí v dokumentu na instrukci <?php echo „Ahoj!“; ?> je funkce volána s parametry $cil=“php“ a $data=“echo \“Ahoj!\“;“.
|
externiEntita($parser, $jmenoEntity, $x, $systemID, $publicID)
K zavolání této mnou definované funkce dojde, když parser narazí v dokumentu XML na externí textovou entitu. Parametr $parser identifikuje parser, který tuto funkci volá. Parametru $jmenoEntity je přiřazen název entity, parametr $x je v současné době prázdný řetězec, parametru $systemID je přiřazen systémový identifikátor externí entity a parametru $publicID veřejný identifikátor externí entity. Pokud tedy např. parser $parser narazí v dokumentu na externí entitu &kniha, která je definována v DTD dokumentu XML jako <!ENTITY kniha SYSTEM „kniha.xml“>, bude funkce volána s parametry $jmenoEntity=“kniha“, $systemID=“kniha.xml“.
|
notace($parser, $zapisNotace, $x, $systemID, $publicID)
K zavolání této mnou definované funkce dojde, když parser narazí v dokumentu XML (v jeho DTD) na deklaraci notace. Parametr $parser identifikuje parser, který tuto funkci volá. Parametru $zapisNotace je přiřazen název notace, parametr $x je v současné době prázdný řetězec, parametru $systemID je přiřazen systémový identifikátor deklarace notace a parametru $publicID veřejný identifikátor deklarace notace. Praktický význam v mém skriptu tato funkce nemá, definoval jsem ji jen pro úplnost.
|
neanalyzEntita($parser, $jmenoEntity, $x, $systemID, $publicID, $jmenoNotace)
K zavolání této mnou definované funkce dojde, když parser narazí v dokumentu XML na deklaraci externí neanalyzované (binární) entity. Parametr $parser identifikuje parser, který tuto funkci volá. Parametru $jmenoEntity je přiřazen název neanalyzované entity, parametr $x je v současné době prázdný řetězec, parametru $systemID je přiřazen systémový identifikátor neanalyzované entity, parametru $publicID veřejný identifikátor neanalyzované entity a parametru $jmenoNotace typ dat neanalyzované entity. Jestliže například parser najde v dokumentu (v jeho DTD) následující deklaraci: <!ENTITY logo SYSTEM „logo.gif“ NDATA gif>, je funkce volána s parametry $jmenoEntity=“logo“, $systemID=“logo.gif“ a $jmenoNotace=“gif“.
|
nedefinovano($parser, $data)
K zavolání této mnou definované funkce dojde, když parser narazí v dokumentu XML na jakýkoli uzel bez zaregistrované obslužné funkce nebo na uzel, k němuž takovouto funkci zaregistrovat nelze. V tomto skriptu ji využiji ke zpracování komentářů a celého prologu dokumentu.
|
Vytvoření parseru a registrace obslužných funkcí
Po definici obslužných funkcí mohu vytvořit parser XML a tyto funkce zaregistrovat.
|
Otevření dokumentu XML
|
Přečtení a zpracování dokumentu XML
Dokument je lépe analyzovat po částech, aby u rozsáhlých údajů nedošlo k zahlcení parseru. Současně je možné alespoň základním způsobem ošetřit případné chyby ve struktuře dokumentu (parser v PHP není schopen zkontrolovat validitu dokumentu, tedy to, zda dokument odpovídá deklarovanému DTD).
|
Uvolnění parseru
|
Využití mocných nástrojů PHP na analýzu XML dokumentů k triviálnímu přepisu jednoduchého dokumentu knihovna.xml je samozřejmě tak trochu škoda. Věřím však, že k prvnímu seznámení s těmito nástroji tento příklad snad poslouží dobře.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Lék na phishing a apatii ve světě e-mailového marketingu
18. března 2024 -
Jak nainstalovat šablonu ve WordPressu
23. července 2024 -
Optimalizace a zlepšení výkonu kódu: tipy a triky
14. srpna 2023
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024