Witaj, Gościu O nas | Kontakt | Mapa
Wortal Forum PHPEdia.pl Planeta Kubek IRC Przetestuj się!

XML - morze możliwości - XPath, XPointer, XInclude

XInclude

XInclude jest standardem który pozwala nam dołączać zewnętrzne dokumenty lub ich fragmenty do pliku XML. XInclude zawiera się w przestrzeni nazw http://www.w3.org/2001/XInclude. W tym namespace mamy dwa elementy - zakładając że zadeklarujemy prefix xi będzie to xi:include oraz xi:fallback. Pierwszy z nich określa lokalizacje jednostki którą chcemy dołączyć - może być to mały zakres XML?a wybrany XPath?em lub cały plik. Może się zdarzyć że XInclude zwróci błąd. Plik lub wybrany zakres który chcemy dołączyć może nie istnieć. Aby obsłużyć błąd XInclude oferuje element xi:fallback.

Rozszerzmy naszą książkę adresową o grupy. Mając wiele kontaktów w pewnym momencie dobrze by było je jakoś uporządkować.

<?xml version="1.0" encoding="UTF-8"?>
<address-book>
    <persons>
        <person id="1">
            <firstname>Jan</firstname>
            <lastname>Kowalski</lastname>
            <email>jan-kowalski@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Warszawa</city>
        </person>
        <person id="2">
            <firstname>Piotr</firstname>
            <lastname>Nowak</lastname>
            <email>piotr-nowak@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Kraków</city>
        </person>
        <person id="3">
            <firstname>Paweł</firstname>
            <lastname>Kwiatkowski</lastname>
            <email>pawel-kwiatkowski@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Warszawa</city>
        </person>
        <person id="4">
            <firstname>Paweł</firstname>
            <lastname>Jankowski</lastname>
            <email>robert-jankowski@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Poznań</city>
        </person>
    </persons>
    <groups>
        <group name="Znajomi">
            <persons>
                <person id="2">
                    <firstname>Piotr</firstname>
                    <lastname>Nowak</lastname>
                    <email>piotr-nowak@gmail.com</email>
                    <phone>000 123 456</phone>
                    <city>Kraków</city>
                </person>
                <person id="3">
                    <firstname>Paweł</firstname>
                    <lastname>Kwiatkowski</lastname>
                    <email>pawel-kwiatkowski@gmail.com
                    </email>
                    <phone>000 123 456</phone>
                    <city>Warszawa</city>
                </person>
            </persons>
        </group>
        <group name="Praca">
            <persons>
                <person id="1">
                    <firstname>Jan</firstname>
                    <lastname>Kowlaski</lastname>
                    <email>jan-kowalski@gmail.com</email>
                    <phone>000 123 456</phone>
                    <city>Warszawa</city>
                </person>
                <person id="4">
                    <firstname>Paweł</firstname>
                    <lastname>Jankowski</lastname>
                    <email>robert-jankowski@gmail.com</email>
                    <phone>000 123 456</phone>
                    <city>Poznań</city>
                </person>
            </persons>
        </group>
    </groups>
</address>

Nie trudno zauważyć że takie rozwiązanie jest kłopotliwe. Gdy ktoś zmieni numer będziemy musieli zmieniać ten numer w kilku miejscach.

Problem ten możemy rozwiązać właśnie dzięki XInclude. Zamiast posiadać te same wpisy kilka razy, będzie je dołączać na podstawie numeru ID.

<?xml version="1.0" encoding="UTF-8" ?>
<address-book xmlns:xi="http://www.w3.org/2001/XInclude">
    <persons>
        <person id="1">
            <firstname>Jan</firstname>
            <lastname>Kowalski</lastname>
            <email>jan-kowalski@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Warszawa</city>
        </person>
        <person id="2">
            <firstname>Piotr</firstname>
            <lastname>Nowak</lastname>
            <email>piotr-nowak@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Kraków</city>
        </person>
        <person id="3">
            <firstname>Paweł</firstname>
            <lastname>Kwiatkowski</lastname>
            <email>pawel-kwiatkowski@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Warszawa</city>
        </person>
        <person id="4">
            <firstname>Paweł</firstname>
            <lastname>Jankowski</lastname>
            <email>robert-jankowski@gmail.com</email>
            <phone>000 123 456</phone>
            <city>Poznań</city>
        </person>
    </persons>
    <groups>
        <group name="Znajomi">
            <persons>
                <xi:include xpointer="xpointer(/address-book/persons/person[@id='1'])" />
                <xi:include xpointer="xpointer(/address-book/persons/person[@id='4'])" />
            </persons>
        </group>
        <group name="Praca">
            <persons>
                <xi:include xpointer="xpointer(/address-book/persons/person[@id='3'])" />
                <xi:include xpointer="xpointer(/address-book/persons/person[@id='4'])" />
            </persons>
        </group>
    </groups>
</address>

Przetwórzmy teraz ten plik używając PHP i DOM:

<?php
$dom = new DOMDocument();
$dom->preserverWhiteSpace = true;
$dom->formatOutput = true;
$dom->load('address-book.xml');
$dom->xinclude();
$dom->save("adress-book-xinclude.xml");

Za XInclude w klasie odpowiedzialna jest metoda xinclude(). Na końcu zapisaliśmy zawartość w nowym pliku żeby móc sprawdzić czy to rzeczywiście działa. Otwierając plik powinniśmy zobaczyć zamiast wpisów xi:include, dołączone właściwe wartości.

Nasza książka może się rozrosnąć, a trzymanie wszystkiego w jednym pliku może stać się nie wygodne. A co gdybyśmy chcieli trzymać grupy kontaktów w oddzielnym pliku, np.: address-book-groups.xml?

Zawartość pliku wyglądała by wtedy następująco:

<?xml version="1.0" encoding="UTF-8" ?>
<address-book xmlns:xi="http://www.w3.org/2001/XInclude">
    <groups>
        <group name="Znajomi">
            <persons>
                <xi:include href="address-book.xml" xpointer="xpointer(/address-book/persons/person[@id='1'])" />
                <xi:include href="address-book.xml" xpointer="xpointer(/address-book/persons/person[@id='4'])" />
            </persons>
        </group>
        <group name="Praca">
            <persons>
                <xi:include href="address-book.xml" xpointer="xpointer(/address-book/persons/person[@id='3'])" />
                <xi:include href="address-book.xml" xpointer="xpointer(/address-book/persons/person[@id='4'])" />
            </persons>
        </group>
    </groups>
</address>

Wycięliśmy element groups wraz z jego dziećmi z pliku address-book.xml, dodając przy wartościach dołączanych atrybut href, wskazujący na plik w którym znajduje się nasz XML z osobami.

« XPath
XSLT »
Informacje na podobny temat:
Wasze opinie
Wszystkie opinie użytkowników: (2)
Opinia
Poniedziałek 05 Styczeń 2009 1:24:49 pm - Cypherq <cypherq_at_gmail.com>

1."<adress -book> <presons>" - chyba <persons>
2. (??) zamiast (''), bardzo ułatwia to czytanie kodu.
3. <adress -book> - <adress-book>
4. < ?xml - <?xml
5. < ?php$dom - <?php $dom ?

Jak również mnóstwo innych pomniejszych literówek. Artykuł wygląda na poprawiany na kolanie. Sprawdzał ktoś w ogóle przed publikacją to to? Merytorycznie może ciekawy, ale dbajcie tez o komfort czytelnika...

Gratulacje
Niedziela 04 Styczeń 2009 11:06:56 am - phpion

Świetny artykuł! Ciekawy i przystępnie napisany. Gratulacje dla autora!

Mentax.pl    NQ.pl- serwery z dodatkiem świętego spokoju...   
O nas | Kontakt | Mapa serwisu
Copyright (c) 2003-2017 php.pl    Wszystkie prawa zastrzeżone    Powered by eZ publish Content Management System eZ publish Content Management System