Na navigaci | Klávesové zkratky

Translate to English… Ins Deutsche übersetzen…

DOMDocument::registerNodeClass je boží

A teď jedna dobrá zpráva ze světa zpracování XML dokumentů v PHP. S příchodem verze 5.2.0 se řady funkcí DOM rozšířily o nováčka jménem registerNodeClass(). K čemu však slouží? Dokumentace to úzkostlivě tají, dokonce i strýček Google cudně mlčí. Tak to se asi nedozvíme. Nejspíš půjde o nějakou hloupost…

The end

Ještě tu jste?

Tak to, ukecali jste mě, prozradím vám význam registerNodeClass. Tato funkce bezpochyby přináší svěží vítr do celé problematiky XML a nastavuje zrcadlo dosavadnímu systému zpracování. Možná více než slova napoví malý příklad.

Jednotlivé třídy DOM je možné v PHP dále rozšiřovat. Například takto si rozšíříme DOMElement o tři šikovné metody:

class dgxElement extends DOMElement
{

    /**
     * Converts to a SimpleXMLElement
     */
    public function toSimple()
    {
        return simplexml_import_dom($this);
    }


    /**
     * Removes this element from the document
     */
    public function remove()
    {
        $this->parentNode->removeChild($this);
    }

    /**
     * Kills all the children. But kindly!
     */
    public function childless($node)
    {
        $this->nodeValue = '';
    }

}

První z nich přetaví uzel na objekt SimpleXML, druhá jej zase odstraní ze stromu dokumentu. A třetí funkce je tuze šikovná, protože zbaví element všech potomků a to vskutku elegantně, bez složitých iterací.

Tohle všechno je velmi krásné, skoro až báječné, nebýt jednoho drobného detailu. Výhod dgxElement využijeme pouze tehdy, pokud element vytvoříme skriptem. V případě, že XML dokument naparsujeme ze souboru, tak bude tvořen pouze standardními objekty DOMElement, DOMAttr, atd.

Této vady na kráse si všimli i američtí inženýři. Po krátké poradě se rozhodli jednat a brzy přišli s řešením. Dali mu politicky korektní název registerNodeClass. A nyní opět pohovořme v jazyce PHP:

$doc = new DOMDocument();

// and now use dgxElement instead of DOMElement!
$doc->registerNodeClass('DOMElement', 'dgxElement');

// parse a XML file
$doc->loadXML('<root><blog name="La Trine"/></root>');

// returns TRUE
echo ($doc->documentElement instanceof dgxElement);

// method toSimple() test:
$simple = $doc->documentElement->toSimple();

foreach ($simple as $blog)
    echo $blog['name'];


// bye bye element <blog>
$doc->documentElement->firstChild->remove();

echo $doc->saveXML(); //  <root/>

Paráda, ne?

Komentáře

  1. d.f.h http://moznosti.cz #1

    avatar

    paráda, jo! :-) s XML pracuju často a rád, tohle se bude určitě hodit. díky za dokumentaci.

    před 10 lety
  2. johno http://johno.jsmf.net/ #2

    avatar

    To vyzerá ako keby objavili Factory pattern. Design patterns v PHP extension? Neverím vlastným očiam.

    před 10 lety | reagoval [7] pete [9] Robajz
  3. ehmo #3

    hned to pomohlo, konecne sa moze ten hnusny import xmlcka prepisat, radost pozerat :)

    před 10 lety | reagoval [9] Robajz
  4. lukas http://www.pro-vlasy.cz/ #4

    Nejak mi nedochazi, proc to PHP 5 vubec pouzivat. Asi tak jedina vyjimecna vlastnost PHP je, ze je (temer) vsude a kazdy s nim (jakz takz) umi. Jenze to plati pro PHP 4 a ne pro PHP 5 (a taky to pro nej nikdy platit nebude, jedina sance by byla dobre zvladnuta propagace PHP 6 spojena se zazrakem).

    Je mi jasny, ze je porad lepsi sporna kompatibilita skriptu PHP 4 ⇒ PHP 5 nez zadna kompatibilita PHP 4 ⇒ uplne_jiny_jazyk, ale presto – podporuje uz konecne PHP 5 unicode (nechce se mi verit, ze by nativni podporu nemelo, ale i presto, ze Googluju jak o zavod, tak nic nevidim)? A dokazu udelat PHP neco elegantneji nez Python?

    před 10 lety | reagoval [6] Ronnie
  5. Jan Tichý http://www.jantichy.cz #5

    avatar

    Tahle funkce je fajn, i když její uvedení nepovažuji až za takový nečekaný zázrak, jak by mohlo vyznít z nadšeného článku. Je to spíš jen logické vyústění něčeho, co tu mělo být už dávno. Vždyť podobných override možností už na různých jiných místech PHPčka existuje celá řada – od definice vlastních funkcí pro obsluhu sessions počínaje až třeba po předefinování vracené Statement třídy u PDO konče.

    před 10 lety
  6. Ronnie #6

    #4 lukasi, Mně zas nedochází, proč se v každé diskusi musí rozpotávat flame PHP vs. ostatní jazyky.

    před 10 lety
  7. pete http://pmatous.net/ #7

    #2 johno, Mě spíš překvapuje že to do DOMDocument-u šoupli až teď, když simplexml to má už delší dobu (simplexml_load_string($input, ‚XML_Node‘))

    před 10 lety
  8. Zdeněk Košťál #8

    avatar

    Stejně nejkrásnější je, jak se u takovýchto příspěvků vždy zredukuje počet komentářů, protože tomu nikdo nerozumí :-D

    před 10 lety
  9. Robajz http://robajz.info #9

    Vážně super :)

    #3 ehmo, Psal jsem kdysi třídu pro import XML, která rozšiřovala DOMDocument a to že nešlo vynutit vlastní třídy pro nody byla fakt bolest. #2 johno Factory asi objevili, ale bylo by fine, kdyby člověk měl k dispozici i tu factory funkci.

    class DOMDocument // jak by to mohlo byt
    {
        public function registerNodeFactory($factoryCallback);
    }
    class DOMDocumentMyImport extends DOMDocument
    {
        public function __construct($version=null , $encoding=null )
        {
            parent::__construct($version , $encoding);
            $this->registerNodeFactory(array($this,'factoryNode'));
        }
        protected function factoryNode(DOMNode $originNode /*nebo co?*/)
        {
             // return new node...
        }
    }
    před 10 lety

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.