DOM XML funkce se do PHP dostaly ve formě stejnojmenného modulu ve verzi 4. Ovšem před verzí PHP 4.2.0 se ještě jednalo o jakési "pseudo-DOM" rozhraní s různými nestandardními funkcemi. Použití XML DOM funkcí v PHP před verzí 4.2.0 tudíž nelze doporučit. Ve verzi 4.2.0 byly DOM XML funkce zásadně přepracovány ve snaze uvést je do souladu s DOM standardem. V současné době lze hovořit o poměrně dobré implementaci DOM Core, i když lze stále najít některé drobné chyby - koneckonců modul je ještě stále ve vývoji (experimental), takže ani není divu. To však neznamená, že by nebylo možné DOM XML funkce nasadit v praxi.
Zvláštnosti DOM v PHP
Zaprvé je potřeba upozornit na skutečnost, že narozdíl od tečkové notace známé z Javascriptu (mimo jiné) používá PHP pro členské metody a vlastnosti objektů odlišnou syntaxi - šipky.
Jestliže standard DOM definuje určité metody a určité vlastnosti objektů, v PHP mají DOM objekty vždy pouze metody. Například vlastnost attributes
, která vrací pole atributů daného elementu, má v PHP podobu metody (funkce).
$attrs = $element->attributes();
Další odlišností od standardu DOM jsou názvy metod a vlastností - jednotlivá slova v názvu nejsou označena počátečními velkými písmeny, nýbrž jsou všechna písmena malá a mezi jednotlivými slovy jsou podtržítka. Ukažme si to na příkladu odlišné syntaxe metody getElementsByTagName()
mezi Javascriptem a PHP.
Javascript:
var elements = el.getElementsByTagName("jmeno_elementu");
PHP:
$elements = $el->get_elements_by_tagname("jmeno_elementu");
Všimněte si, že v tomto konkrétním případě je název metody v PHP mírně nedůsledný - správnější by zřejmě byla podoba get_elements_by_tag_name()
. I na takovéto drobnosti je nutné si dávat pozor.
Vytvoření objektu DOM XML Dokumentu
Před tím, než se začneme procházet XML dokumentem pomocí DOM metod, nebo provádět jakékoliv změny v dokumentu, je potřeba načíst XML dokument a vytvořit jeho DOM reprezentaci. Pro tento účel existují dvě funkce - domxml_open_mem()
a domxml_open_file()
. První z nich vytváří objekt typu DOM Document z XML dokumentu ve formě textového řetězce (string) a druhá jej načítá rovnou ze souboru.
Vytvoření DOM XML dokumentu z textového řetězce
Pokud máme XML dokument ve formě stringu, stačí jej předat funkci domxml_open_mem()
jako parametr:
$xml = "<element>obsah elementu</element>";
$xmlDoc = domxml_open_mem($xml);
Vytvoření DOM XML dokumentu ze souboru
Načtení XML dokumentu ze souboru a vytvoření objektu typu DOM dokument zajišťuje funkce
domxml_open_file()
. Jako parametr této funkce je potřeba uvést cestu k souboru s XML dokumentem.
$xmlSrc = "cesta/k/dokumentu.xml";
$xmlDoc = domxml_open_file($xmlSrc);
Výše uvedený kód vám však bude fungovat pouze na Linuxu - na Windows systémech je potřeba dosadit úplnou cestu k souboru ve filesystému (např. c:/web/data/dokument.xml
), i kdyby se soubor s XML dokumentem nacházel ve stejném adresáři.
Vytvoření prázdného DOM XML dokumentu
Kromě načtení již existujícího XML dokumentu můžeme v PHP k vytváření XML dokumentu přistoupit "od čistého stolu" - tj. vytvořit úplně nový, prázdný DOM XML dokument. Pro tento účel máme k dispozici funkci domxml_new_doc()
. Jediným parametrem funkce je verze XML - prakticky tedy string "1.0".
$xmlDoc = domxml_new_doc("1.0");
$root = $xmlDoc->create_element("root");
$xmlDoc->append_child($root);
$content = $xmlDoc->create_text_node("nějaký textový obsah");
$root->append_child($content);
Předchozí příklad ukazuje vytvoření prázného DOM XML dokumentu, vložení kořenového elementu a textového nodu. Analogickým způsobem můžeme vytvořit jakýkoliv XML (a potažmo XHTML) dokument striktně pomocí DOM metod. V některých případech může být velice efektivní vytvářet a případně za chodu modifikovat XML dokumenty - když však naše "dokumentově-objektové dílo" zdárně dokončíme, vyvstane palčivá otázka, jak tuto subtilní objektovou reprezentaci zhmotnit, jinými slovy - jak z ní vytvořit XML dokument jako textový řetězec nebo uložit do souboru.
Transformace DOM XML dokumentu na textový řetězec
Potřebujeme-li vytvořit XML dokument ve formě textového řetězce (který poté můžeme např. vypsat na výstup zasílaný klientovi), použijeme metodu objektu DOM dokumentu dump_mem()
. Metoda má dva nepovinné parametry - prvním je logická proměnná určující, jestli bude výstup formátován (odsazení tagů atd.), nebo nikoliv. Druhý parametr určuje výstupní kódování.
$xmlString = $xmlDoc->dump_mem(true, "ISO-8859-2");
Předchozí příklad ukazuje vytvoření formátovaného dokumentu s kódováním ISO-8859-2.
Transformace DOM XML dokumentu na HTML
DOM XML funkce v PHP obsahují také metodu pro vytvoření textového řetězce ve formě HTML dokumentu. Metoda se nazývá html_dump_mem()
a nemá žádné parametry. Výsledkem je HTML dokument ve formě textového řetězce.
$htmlString = $xmlDoc->html_dump_mem();
Transformace DOM XML nodu na textový řetězec
Stejně, jako lze převést na řetězec celý DOM XML dokument, můžeme v PHP totéž udělat s kterýmkoliv uzlem (nodem). Stačí použít metodu dump_node()
, které jako parametr dáme objekt příslušného DOM nodu.
$nodes = $xmlDoc->get_elements_by_tagname("uzel");
$nodeString = $xmlDoc->dump_node($nodes[0]);
Uložení XML dokumentu do souboru
Stejně, jako lze načíst XML dokument přímo ze souboru, můžeme vytvořit z DOM reprezentace XML dokumentu rovnou soubor. Lze to udělat pomocí metody dump_file()
. Metoda má tři parametry. Prvním, povinným, je jméno souboru (případně i s cestou k tomuto souboru), který bude vytvořen. Další dva parametry jsou booleanovské a nepovinné - compressionmode (určující, jestli bude XML dokument komprimován - popravdě řečeno, nemám tušení, co tento parametr vlastně dělá) a format (určující, jestli bude XML dokument přehledně formátován).
$xmlLength = $xmlDoc->dump_file("dokument.xml", false, true);
Opět upozorňuji na to, že na Windows je potřeba vždy uvádět úplnou, absolutní cestu k souboru. Metoda zapíše vzniklý soubor a vrací velikost tohoto souboru v bytech.
XPath
V DOM XML funkcích v PHP se našlo místo i pro implementaci XPath - v mnoha případech není efektivnějšího způsobu, jak se dostat k určitému nodu (či množině nodů), než nám poskytne jediný XPath dotaz. Nyní si ukážeme, jak na to.
Nejprve je potřeba vytvořit objekt "kontextu" pro XPath dotaz. Tento objekt vytvoříme pomocí metody DOM XML dokumentu xpath_new_context()
. Tato metoda nemá žádné parametry. Nově vzniklý objekt má metodu xpath_eval()
, které předáme jediný parametr - XPath dotaz. Výsledný objekt má vlastnost nodeset, která vrací pole všech nodů, které odpovídají XPath dotazu.
$xp = $xmlDoc->xpath_new_context();
$xp_result = $xp->xpath_eval("//ulice");
$node_array = $xp_result->nodeset;
Příjemnou vlastností XPath dotazů je to, že vrácené nody lze libovolně dále podrobovat jakýmkoliv DOM transformacím, stejně, jako kdybychom tyto nody získaly standardním způsobem.
Abychom si zjednodušili práci s XPath dotazy a jejich výsledky, můžeme si vytvořit vlastní objekt, který bude zapouzdřovat celou proceduru a po vzoru XPath metod v MSXML parseru si definujeme 2 členské metody tohoto objektu - select_nodes()
, která bude vracet pole všech nodů, odpovídajících dotazu, a metodu select_single_node()
, která bude vracet pouze pouze jediný node. Tuto druhou metodu využijeme typicky v případě, že hledáme pouze jediný uzel (např. dle hodnoty atributu typu ID). Zde je kód příslušné třídy:
class XP
{
var $xp_context;
function XP($xmlDoc)
{
$this->xp_context = $xmlDoc->xpath_new_context();
}
function select_nodes($xp_expression)
{
$result = $this->xp_context->xpath_eval($xp_expression);
return $result->nodeset;
}
function select_single_node($xp_expression)
{
$result = $this->select_nodes($xp_expression);
return $result[0];
}
}
Použití je velice jednoduché - vytvoříme objekt, kterému předáme jako parametr DOM XML dokument a poté již můžeme pomocí metod select_node()
a select_single_node()
provádět XPath dotazy.
$XP = new XP($xmlDoc);
$XP->select_single_node("//*[@id=`cerveny-tulipan`]"));
Závěrem
Tímto končí nejen tento díl, ale i celý seriál o XML a jeho používání v některých rozšířených webových nástrojích. Jeho cílem bylo nejen popsat samotné XML, ale také ukázat, k čemu lze dnes na webu toto nejprotěžovanější dítko W3C prakticky využít, kde je nasazení XML výhodné, kde má praktická aplikace slabiny a kde se rýsují slibné perspektivy. Doufám, že tento cíl byl splněn co možná nejlépe.