XML pro web aneb od teorie k praxi, 17.díl

Dnes se podíváme na další funkce XML parseru v PHP.

Další ovladače událostí

Minule jsme si ukazovali, jakým způsobem lze zaregistrovat funkce pro obsluhu elementů, znakových dat, procesních instrukcí a také registraci výchozí obslužné funkce. Tím jsme ovšem nevyčerpali všechny možnosti obsluhy událostí. Nyní si ukážeme ty zbývající.

Obsluha neanalyzovaných entit

Pro registraci funkce, která bude obsluhovat neanalyzované entity, je k dispozici funkce xml_set_unparsed_entity_decl_handler(). Jako první parametr je nutné předat identifikátor XML parseru a jako druhý parametr název funkce, která bude provádět obsluhu.

xml_set_unparsed_entity_decl_handler($XmlP, `fceProObsluhuNeparsEntit`);

Obslužná funkce bude již tradičně přijímat od XML parseru určité argumenty, v tomto případě jich ovšem bude poněkud více - přesněji řečeno šest. Vyjmenujeme si popořadě všechny. Prvním argumentem je identifikátor XML parseru. Druhým je jméno entity. Třetí argument base nenajde v současné době v podstatě žádné využití (XML parser vrací vždy prázný řetězec), zřejmě bude nějakým způsobem "zužitkován" v příštích verzích. Čtvrtým argumentem je systémový identifikátor a pátým veřejný identifikátor. Poslední, šestý argument nese název notace.

function fceProObsluhuNeparsEntit($XmlP, $ent_name, $b, $system_id, $public_id, $not_name)
{
	if($not_name==`gif`)
	{
		echo `<img src="`.$system_id.`" alt="Klepněte pro větší obrázek" />`;
	}
}

Výše uvedený příklad ukazuje použití obslužné funkce pro vypsání html kódu obrázku ve formátu .gif.

Obsluha externích analyzovaných entit

Obsluhu analyzovaných externích entit zaregistrujeme funkcí xml_set_external_entity_ref_handler(), které předáme dva parametry - jedná o stejné parametry, jako v předchozím případě.

xml_set_external_entity_ref_handler($XmlP, `fceProObsluhuAnalyzEntit`);

Obslužná funkce přijímá tentokrát "pouze" pětici parametrů. Po obligátním identifikátoru XML parseru je to řetězec obsahující název entity, a dále v současné době nevyužitelný atribut base. Čtvrtým a pátým argumentem je systémový identifikátor a veřejný identifikátor.

function fceProObsluhuAnalyzEntit($XmlP, $ent_name, $b, $system_id, $public_id)
{
	echo `<a href="`.$system_id.`">`.$ent_name.`"</a>`;
}

Příklad ukazuje prostý výpis HTML odkazu, jelikož se však jedná o analyzovanou externí entitu, nic nám nebrání tuto entitu načíst a parsovat stejným způsobem, jako původní XML soubor.

Obsluha notací

Další částí XML dokumentu, kterou můžeme obsluhovat k tomu definovanou funkcí, je notace. Registrace se provádí funkcí xml_set_notation_decl_handler(). Parametry jsou znovu zcela totožné (identifikátor XML parseru a název obslužné funkce).

xml_set_notation_decl_handler($XmlP, `fceProObsluhuNotaci`);

Obslužná funkce dostává opět pětici parametrů, které jsou v podstatě totožné, jako u obslužné funkce externí analyzované entity (pro upřesnění - druhým parametrem je samozřejmě jméno notace). Nedokážu si příliš představit, k čemu užitečnému by se tato obsluha dala prakticky využít, nicméně je k dispozici.

function fceProObsluhuNotaci($XmlP, $not_name, $b, $system_id, $public_id)
{
	//kod funkce...
}

Získání podrobností o aktuálním stavu analýzy

V kterémkoliv okamžiku analýzy je možné získat index aktuálně analyzovaného bytu, aktuální řádky, nebo aktuálního sloupce v XML dokumentu.

Získání aktuálního byte indexu

Index aktuálního bytu vrací funkce xml_get_current_byte_index(). Jako jediný parametr je nutné této funkci předat identifikátor XML parseru.

$byte_index = xml_get_current_byte_index($XmlP);

Získání čísla aktuální řádky

Pro zjištění tohoto údaje existuje funkce xml_get_current_line_number(), která dostává opět jediný parametr - identifikátor XML parseru.

$line_index = xml_get_current_line_number($XmlP);

Získání čísla aktuálního sloupce

Do třetice všeho dobrého, funkce xml_get_current_column_number() vrací číslo aktuálního sloupce (pořadí aktuálně zpracovávaného znaku na dané řádce XML dokumentu). Nebude pro vás zřejmě žádné překvapení, že tato funkce vyžaduje jediný argument - jaký, to jistě není nijak obtížné uhodnout :).

$col_index = xml_get_current_column_number($XmlP);

Získání chybových hlášení

Pokud XML parser z nějakého důvodu nemůže zpracovat XML data, skončí analýzu. Chybu, která způsobila skončení parsování, lze samozřejmě také identifikovat. Chybový kód nám vrátí funkce xml_get_error_code(), která jako parametr dostává identifikátor XML parseru. Pokud získaný chybový kód předáme jako argument další funkci xml_error_string(), získáme obsáhlejší popis chyby.

echo xml_error_string(xml_get_error_code($XmlP));

Pro chybové kódy jsou definovány následující konstanty:

XML_ERROR_NONE
XML_ERROR_NO_MEMORY
XML_ERROR_SYNTAX
XML_ERROR_NO_ELEMENTS
XML_ERROR_INVALID_TOKEN
XML_ERROR_UNCLOSED_TOKEN
XML_ERROR_PARTIAL_CHAR
XML_ERROR_TAG_MISMATCH
XML_ERROR_DUPLICATE_ATTRIBUTE
XML_ERROR_JUNK_AFTER_DOC_ELEMENT
XML_ERROR_PARAM_ENTITY_REF
XML_ERROR_UNDEFINED_ENTITY
XML_ERROR_RECURSIVE_ENTITY_REF
XML_ERROR_ASYNC_ENTITY
XML_ERROR_BAD_CHAR_REF
XML_ERROR_BINARY_ENTITY_REF
XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
XML_ERROR_MISPLACED_XML_PI
XML_ERROR_UNKNOWN_ENCODING
XML_ERROR_INCORRECT_ENCODING
XML_ERROR_UNCLOSED_CDATA_SECTION
XML_ERROR_EXTERNAL_ENTITY_HANDLING

Nastavení a získání předvoleb XML parseru

XML parseru je možné pomocí funkce xml_parser_set_option() nastavit dvě předvolby. Funkce dostává tři parametry - identifikátor XML parseru, konstantu jedné ze dvou předvoleb a konečně hodnotu této předvolby. Konstanta první předvolby je XML_OPTION_CASE_FOLDING - jedná se v podstatě o kontrolu nad tím, zda parser předává názvy elementů transformované na velká písmena (uppercase), nebo nikoliv. Ve výchozím nastavení XML parser provádí transformaci na velká písmena (hodnota true), takže pokud tomuto chování potřebujeme z nějakého důvodu zabránit, můžeme nastavit tuto předvolbu následujícím způsobem:

xml_parser_set_option($XmlP, XML_OPTION_CASE_FOLDING, false);

Druhou předvolbou lze nastavit cílové kódování (předdefinovaná konstanta pro tuto předvolbu je XML_OPTION_TARGET_ENCODING). Cílové kódování vstupuje do hry, když parser předává data obslužné funkci - v základním nastavení je cílové kódování shodné se zdrojovým kódováním (které lze ovlivnit parametrem funkce xml_parser_create(). Pokud potřebujeme nastavit jiné cílové kódování, uděláme to například takto:

xml_parser_set_option($XmlP, XML_OPTION_TARGET_ENCODING, "US-ASCII");

Na výběr máme jen tři možná kódování - UTF-8, US-ASCII a ISO-8859-1.

Zjištění hodnoty obou předvoleb je možné provést pomocí funkce xml_parser_get_option (), které předáme 2 parametry - identifikátor XML parseru a předvolbu ve formě předdefinované konstanty.

$encoding = xml_parser_get_option($XmlP, XML_OPTION_TARGET_ENCODING);

Parsování do struktury pole

Na závěr si ukážeme zajímavou funkci, která představujeme zřejmě nejjednodušší způsob analýzy XML dokumentu, který může být v některých případech velmi efektivní. Funkce se jmenuje xml_parse_into_struct() a má za následek vytvoření dvou polí, ve kterých nelezneme všechna data z XML dokumentu. Ukažme si nejprve malý příklad analýzy XML dokumentu s pomocí této funkce.

// v promenne $xmlDoc mame jiz pripraven XML dokument jako textovy retezec
$XmlP = xml_parser_create();
xml_parse_into_struct($XmlP,$xmlDoc,$vals,$index);
xml_parser_free($XmlP);

Jak vidíte, samotná analýza proběhla během tří řádků kódu. Funkce xml_parse_into_struct() má čtyři parametry - identifikátor XML parseru, XML dokument jako textový řetězec, proměnnou, ve které bude uloženo první pole hodnot a nakonec proměnnou, ve které bude uloženo druhé "indexové" pole. Poslední parametr je nepovinný.

Po provedení analýzy jsou výsledná pole uložena v proměnných, které jsme předali této funkci jako třetí a čtvrtý parametr. Abychom získali lepší představu o tom, jaká je struktura výsledných polí, vypíšeme si je následujícím kódem.

echo "<pre>";
echo "INDEXOVE POLE:\n";
print_r($index);
echo "\nPOLE HODNOT:\n";
print_r($vals);
echo "</pre>";

V poli hodnot odpovídá každý prvek jedné části XML dokumentu, přičemž sám je asociativním polem s následujícími indexy: tag (název tagu), value (textový obsah), level (úroveň zanoření), type (typ - open pro počáteční tag, close pro koncový tag, complete pro element prázdný nebo pouze s textovým obsahem a cdata pro blok textových dat mezi elementy) a attributes (asociativní pole atributů název => hodnota).

Indexové pole je asociativní, indexem prvku je vždy název elementu, prvek je sám polem, které obsahuje indexy všech výskytů daného elementu (či k němu příslušejících částí typu cdata) - tyto indexy odpovídají indexům v poli hodnot. Pro lepší představu se odívejte na příklad, kterak je rozparsován krátký XML dokument, který z minulých dílů seriálu jistě důvěrně znáte.

Příště se podíváme na odlišný přístup k XML v PHP založený na DOM rozhraní.

Váš názor Další článek: Průběžný update dnešního článku o ADSL

Témata článku: Software, Programování, Funkce, Odlišné zjištění, Byte, Echo, Následující řádek, Textové pole, Pre, Code, Index, Malý příklad, Jediný způsob, Kody, Pole, Textový řetězec, Jediný cíl, XML, Teorie, Element

Určitě si přečtěte


Aktuální číslo časopisu Computer

Jak rychlé je nabíjení bez drátů?

Test 11 sluchátek pro hráče

Aplikace, které vám zachrání dovolenou

Kompletní přehled datových tarifů