2006.03_Generowanie kodu XML z pakietem XML_Serializer_[XML].pdf
(
501 KB
)
Pobierz
440385809 UNPDF
PEAR
Generowanie kodu XML
z pakietem XML_Serializer
Aaron Wormus
Stopień trudności:
ll
l
Przedstawiamy kolejny bardzo przydatny
pakiet PEAR'owy, tym razem związany z XML.
W artykule pokażemy zastosowanie XML-owego
niezbędnika PHP, czyli pakietu XML_Serializer,
pozwalającego szybko i w łatwy sposób
generować dokumenty XML.
XML pod koniec lat 90., po-
wszechne podejście do tego
języka uległo poważnym zmianom. Spe-
cyikację XML pierwotnie opracowała gru-
pa robocza W3C złożona z przedstawicieli
wielu znanych korporacji informatycznych,
więc w marketingowej gorączce związanej
w utworzeniem nowego, rozszerzalnego
języka znaczników obsługa XML-a była
dodawana do wielu programów tylko po
to, by dołożyć najnowszy chwytliwy skrót
do opisu produktu.
Z biegiem lat gorączka ostygła i za-
częto używać XML-a do celów, do któ-
rych został stworzony. Obecnie można po-
wiedzieć, że XML zadomowił się na do-
bre w informatyce, a w dodatku znajdu-
je zastosowanie w miejscach, o których
się autorom pierwotnej specyikacji na-
wet nie śniło. Formaty XML-owe spotyka-
my na każdym kroku, od protokołów Web
Services poprzez eksport danych z apli-
kacji po standard Internet Content Syndi-
cation, a wraz z popularyzacją technolo-
gii AJAX XML coraz częściej pojawiają się
również na zwykłych stronach interneto-
wych. W obliczu wszechobecności XML-a
we współczesnej informatyce, umiejętność
tworzenia i parsowania kodu XML stała się
koniecznością dla każdego programisty.
Oczywiście XML znalazł również dro-
gę do świata PHP, gdzie zadomowił się na
dobre w różnorodnych zastosowaniach:
formatowaniu dokumentów, składowaniu
danych, protokołach SOAP i XML-RPC
i wielu innych.
W SIECI
1.
http://pear.php.net/package/
XML_Serializer
– strona główna pakietu
XML_Serializer
2.
http://xulplanet.com
– XULPlanet, ciekawa witry-
na o języku XUL
3.
http://imdb.com
– IMDB, czyli Internet Movie
Data Base
Co należy wiedzieć...
Powinieneś się dobrze orientować
w tematyce XML.
Co obiecujemy...
Pokażemy jak generować różnego
rodzaju dokumenty XML z pomocą
pakietu XML_Serializer
76
www.phpsolmag.org
PHP Solutions Nr 3/2006
O
d czasu stworzenia standardu
XML_Serializer
PEAR
Słowo o XML-u
Zanim zajmiemy się samym pakietem
XML_Serializer, nie zawadzi pokrótce
przyjrzeć się formatowi i strukturze doku-
mentów XML.
Twórcy specyikacji XML wzorowa-
li się na standardzie języka znaczników
SGML (ang.
Standard General Markup
Language
), opracowanym jeszcze w la-
tach 80. jako format tekstowy nadają-
cy się do przetwarzania przez kompu-
ter. Ze względu na wysoki stopień ogól-
ności SGML był jednak językiem bar-
dzo skomplikowanym, stąd też potrze-
ba opracowania prostszej jego wersji,
nadającej się do wykorzystania w Inter-
necie i niewymagającej pełnego parse-
ra SGML do przetwarzania dokumentów.
XML jest więc podzbiorem języka SGML
i opiera się na podobnych do niego za-
łożeniach, ale z uwzględnieniem dodat-
kowych ograniczeń mających na celu
uproszczenie procesu parsowania.
Listing 1 przedstawia przykłado-
wy kod prostego dokumentu XML opi-
sującego moje ulubione ilmy. XML wy-
gląda znajomo dla każdego, kto zna
HTML. Nieprzypadkowo – oba języ-
ki są podzbiorami ogólniejszego forma-
tu SGML. Dokument zaczyna się od de-
klaracji XML, określającej wersję forma-
tu XML oraz metodę kodowania tekstu.
W przypadku dokumentów w Unikodzie,
w deklaracji XML należy umieścić atrybut
encoding = "utf-8"
.
Ciało dokumentu XML stanowi je-
den znacznik nadrzędny, zawierają-
cy całą resztę dokumentu. W przykła-
dzie z Listingu 1 znacznikiem nadrzęd-
nym jest
<movies>
, w którym znajduje
się wiele znaczników
<movie>
. Na ra-
zie dokument nie zawiera zbyt dużo in-
formacji, może poza tym, że lubię ilmy
z dobrą ścieżką dźwiękową. Listing 2
przedstawia ten sam dokument roz-
budowany o dodatkowe znaczniki za-
gnieżdżone i atrybuty.
Specyikacja XML znacznie oczywi-
ście wykracza poza te proste przykłady,
ale dla potrzeb tego artykułu więcej infor-
macji o samym XML-u nie będziemy po-
trzebować.
Pakiet XML_Serializer nosi oznacze-
nie
beta
, jednak nie wynika ono z jako-
ści kodu, a jedynie sygnalizuje możli-
wość przyszłych zmian w API. Zgodnie
ze standardami PEAR, oznaczenie pa-
kietu jako stabilnego (
stable
) jest równo-
znacznie zamrożeniu API w celu utrzy-
mania kompatybilności. Z tego też wzglę-
du twórcy intensywnie rozwijanych pakie-
tów utrzymują je w stanie
beta
do czasu
osiągnięcia przez API dojrzałości gwa-
rantującej brak poważniejszych zmian
w przyszłości.
Praca z pakietem
XML_Serializer
Zanim zagłębimy się w mechanizmy
funkcjonowania pakietu XML_Seriali-
zer, przyjrzyjmy się kodowi pokazujące-
mu, jak łatwo generować kod XML z po-
mocą tego narzędzia (Listing 3). Zaczy-
namy od dołączenia pliku zawierającego
kod klasy
XML_Serializer
, po czym two-
rzymy tablicę zawierającą dane oraz ta-
blicę zawierającą opcje, na podstawie
których XML_Serializer będzie genero-
wać kod XML.
Tworząc instancję klasy
XML_Serializer
przekazujemy konstruktorowi tablicę opcji,
Instalacja pakietu
XML_Serializer
XML_Serializer jest zależny od kilku in-
nych pakietów PEAR, więc instalacja
wymaga wykonania następującego po-
lecenia:
pear install --alldeps xml_
serializer-beta
. Spowoduje to zainstalo-
wanie pakietów: XML_Serializer, XML_Util
i XML_Parser.
Listing 3.
Generowanie kodu XML z pomocą pakietu XML_Serializer
require_once
'XML/Serializer.php'
;
$movies
=
array
(
"Piąty Element"
,
"High Fidelity"
)
;
$options
=
array
(
'rootName'
=
>
'movies'
,
'defaultTagName'
=
>
'movie'
)
;
$serializer
= &
new
XML_Serializer
(
$options
)
;
$status
=
$serializer
-
>
serialize
(
$movies
)
;
$xml
=
$serializer
-
>
getSerializedData
()
;
header
(
'Content-type: text/xml'
)
;
echo
$xml
;
Listing 1.
Lista ulubionych ilmów
w prostym dokumencie XML
<
?xml version=
"1.0"
?
>
<
movies
>
<
movie
>
Piąty Element
<
/movie
>
<
movie
>
High Fidelity
<
/movie
>
<
/movies
>
Listing 4.
Generowanie kodu XML w trybie simplexml
Listing 2.
Lista ulubionych ilmów
z nieco bardziej szczegółowymi
informacjami
$movies
=
array
(
'movie'
=
>
array
(
'Piąty Element'
,
'High Fidelity'
))
;
$options
=
array
(
'rootName'
=
>
'movies'
,
'mode'
=
>
'simplexml'
)
;
Listing 5.
Dodawanie atrybutów do znaczników XML za pomocą
tablicy asocjacyjnej
<
movies
>
<
movie name=
"Piąty Element"
>
<
writer
>
Luc Besson
<
/writer
>
<
year
>
1997
<
/year
>
<
imdb
>
tt0119116
<
/imdb
>
<
/movie
>
<
movie name=
"High Fidelity"
>
<
writer
>
Nick Hornby
<
/writer
>
<
year
>
2000
<
/year
>
<
imdb
>
tt0146882
<
/imdb
>
<
/movie
>
<
/movies
>
$movies
=
array
(
array
(
'attr'
=
>
array
(
'name'
=
>
'Piąty Element'
)
,
"writer"
=
>
"Luc Besson"
,
"year"
=
>
"1997"
,
"imdb"
=
>
"tt0119116"
)
,
array
(
'attr'
=
>
array
(
'name'
=
>
'High Fidelity'
)
,
"writer"
=
>
"Nick Hornby"
,
"year"
=
>
"2000"
,
"imdb"
=
>
"tt0146882"
))
;
$options
=
array
(
'rootName'
=
>
'movies'
,
'attributesArray'
=
>
"attr"
,
'defaultTagName'
=
>
'movie'
)
;
PHP Solutions Nr 3/2006
www.phpsolmag.org
77
PEAR
XML_Serializer
Tabela 1.
Niektóre opcje pakietu XML_Serializer
Nazwa Opis
indent Ciąg znaków używany do tworzenia wcięć
linebreak Znak nowej linii (domyślnie \n)
addDecl Dodanie deklaracji XML
encoding Kodowanie znaków w dokumencie
defaultTagName Domyślna nazwa używana w przypadku braku jawnie określonego znacznika
scalarAsAttribute Serializacja wszystkich wartości jako atrybutów; może dotyczyć tylko wybranych znaczników
indentAttributes Wyrównanie atrybutów w pionie w obrębie znacznika
addDoctype Dodanie deklaracji XML Doctype
doctype Ciąg znaków lub tablica z deklaracją Doctype
rootName Ciąg znaków z nazwą znacznika głównego
rootAttributes Atrybuty znacznika głównego
attributesArray Klucz wskazujący tablicę atrybutów dla znacznika macierzystego
contentName Klucz wskazujący wartość używaną jako treść znacznika macierzystego; opcja używana z attributesArray
commentName Treść komentarza
tagMap Odwzorowania nazw znaczników
mode Opcja trybu – ustawienie trybu simplexml spowoduje wykorzystanie klucza wartości macierzystej jako nazwy
znacznika
overrideOptions Pozwala opcjom ustawionym za pomocą setOption() lub setOptions() przesłaniać opcje przekazane w konstruktorze
po czym możemy pobrać dane seriali-
zowane do kodu XML wywołując metodę
getSerializedData()
. Kod z Listingu 3
zwraca dane XML odpowiadające przy-
kładowi z Listingu 1. Opcje generowania
XML-a można też zmieniać już po utwo-
rzeniu instancji
XML_Serializer
za po-
mocą metod
setOption()
i
setOptions()
.
Jeśli opcje przekazane za pomocą
setOption()
mają przesłonić opcje pier-
wotnie przekazane konstruktorowi, na-
leży ustawić parametr
overrideOptions
na
true
.
Przyglądając się kodowi XML z do-
tychczasowych przykładów nietrudno do-
strzec podobieństwo między strukturą
drzewa znaczników XML a strukturą ta-
blicy asocjacyjnej w PHP. XML_Serializer
wykorzystuje to właśnie podobieństwo
– jak widać z przykładu, wystarczy tabli-
ca z danymi i kilka opcji określających
sposób generowania kodu XML.
Zapoznanie się ze wszystkimi do-
stępnymi opcjami jest istotnym elemen-
tem opanowania pakietu XML_Serializer.
Na podstawie tablicy danych można wy-
generować dowolnego rodzaju kod XML
– wystarczy tylko podać odpowiednie
opcje, a niekiedy dodatkowo zmodyiko-
wać strukturę tablicy, by dokładniej odpo-
wiadała strukturze pożądanego dokumen-
tu XML. Tabela 1 przedstawia najważniej-
sze opcje, z których wiele poznamy na
kolejnych przykładach. Dostępne są też
inne opcje, ale dla potrzeb tego artykułu
ich znajomość nie jest konieczna.
Listing 6.
Kod XML wygenerowa-
ny z opcją traktowania wszystkich
wartości jako atrybutów
<
movies
>
<
movie imdb=
"tt0119116"
name=
"Piąty Element"
writer=
"Luc Besson"
year=
"1997"
/
>
<
movie imdb=
"tt0146882"
name=
"High Fidelity"
writer=
"Nick Hornby"
year=
"2000"
/
>
<
/movies
>
Tryby działania
W pierwszym przykładzie wykorzy-
staliśmy prostą tablicę jednowymiaro-
Listing 7.
XML z dodatkowymi
informacjami o postaciach z ilmów
<
movies
>
<
movie name=
'Piąty Element'
>
<
writer
>
Luc Besson
<
/writer
>
<
year
>
1997
<
/year
>
<
imdb
>
tt0119116
<
/imdb
>
<
character name=
'Leeloo'
>
<
actor
>
Milla Jovovich
<
/actor
>
<
imdb
>
nm0000170
<
/imdb
>
<
/character
>
<
character name=
'Korben Dallas'
>
<
actor
>
Bruce Willis
<
/actor
>
<
imdb
>
nm0000246
<
/imdb
>
<
/character
>
<
/movie
>
<!-- ... -->
<
/movies
>
Rysunek 1.
Interfejs dla skryptu pobierającego dane o ilmach z bazy IMDB
78
www.phpsolmag.org
PHP Solutions Nr 3/2006
XML_Serializer
PEAR
wą, a nazwy znaczników XML wska-
zaliśmy za pomocą opcji
rootName
i
defaultTagName
. XML_Serializer po-
zwala też osiągnąć ten sam efekt w inny
sposób, co w naszym prostym przykła-
dzie nie jest może konieczne, ale bar-
dzo się przydaje w przypadku bardziej
złożonych dokumentów XML.
Za pomocą opcji
mode
możemy usta-
wić tryb działania
simplexml
, w którym z
każdą wartością tablicy kojarzona jest
nazwa klucza tablicy nadrzędnej, odpo-
wiadająca nazwie znacznika. W trybie
domyślnym można podać tylko jedną
wartość
defaultTagName
, podczas gdy
tryb
simplexml
pozwala jawnie określać
nazwy znaczników na poszczególnych
poziomach, co daje znacznie większą
kontrolę nad strukturą dokumentu XML.
Kod z Listingu 4 generuje identyczny
XML, jak przykład wcześniejszy, ale tym
razem korzystając z trybu
simplexml
.
Decyzja o wyborze trybu w dużym
stopniu zależy od rodzaju generowa-
nego kodu XML. Tryb domyślny jest ła-
twy w obsłudze i w wielu przypadkach
sprawdza się zupełnie dobrze, jednak
w przypadku bardziej złożonych doku-
mentów jedyną możliwością jest tryb
simplexml
. Pewną wadą pracy w trybie
simplexml
jest konieczność tworzenia
znacznie bardziej rozbudowanych ta-
blic danych.
XML_Serializer udostępnia kilka
metod pracy z atrybutami. Pierw-
szym sposobem jest wykorzysta-
nie opcji
attributesArray
, pozwalają-
cej na przekazanie klucza deiniujące-
go tablicę zawierającą nazwy i warto-
ści atrybutów, które mają być dodane
do znacznika macierzystego. W kodzie
z Listingu 5 klucz ten nosi nazwę
attr
.
Wskazanie tak przygotowanej tablicy
w opcjach przekazywanych obiekto-
wi klasy
XML_Serializer
daje w wyniku
kod XML z Listingu 2.
Dość często traia się kod XML,
w którym wszystkie wartości są składo-
wane jako atrybuty, czyli nie ma żadnych
wartości w obrębie samych znaczników.
Jeśli tak faktycznie jest, to można usta-
wić opcję
scalarAsAttributes
na
true
,
co spowoduje traktowanie wszystkich
wartości kluczy w ramach danego znacz-
nika jako atrybutów. Listing 6 pokazuje
kod XML wygenerowany z tych samych
danych po podaniu tej opcji.
żemy w tej samej tablicy umieścić dwóch
kluczy o takiej samej nazwie
character
.
Moglibyśmy nie używać klucza, ale wte-
dy XML_Serializer użyłby klucza domyśl-
nego, któremu wcześniej przypisaliśmy
wartość
movie
– a zupełnie nie o to nam
chodzi.
Rozwiązanie problemu wymaga
przejścia we wspomniany wcześniej tryb
simplexml
i modyikacji struktury tabli-
cy. Dla zwiększenia czytelności podzieli-
łem jedną rozbudowaną tablicę na dwie
mniejsze. W rzeczywistości dane bę-
dą najczęściej pobierane z zewnętrzne-
go źródła (na przykład bazy danych lub
usługi sieciowej), więc nie ma potrzeby
operowania na dużych i niewygodnych
tablicach zagnieżdżonych. Dla potrzeb
naszego przykładu tablice dobrze jednak
ilustrują proces generowania kodu wy-
nikowego – Listing 8 pokazuje deinicje
odpowiednich tablic.
Rzeczywisty przykład
Na tym etapie wiemy już, na czym pole-
ga generowanie kodu XML za pomocą
pakietu XML_Serializer, pora więc wyko-
rzystać tę wiedzę w praktyce i wygenero-
wać coś, co mogłoby się przydać w rze-
czywistych zastosowaniach. W tym ce-
lu wygenerujemy plik w formacie XUL
– schemacie XML używanym do dei-
niowania struktury interfejsu użytkowni-
ka w przeglądarkach z rodziny Mozilla.
Wykorzystamy tablicę danych z ostat-
niego przykładu, po czym podając od-
powiednie opcje przetworzymy ją do po-
staci poprawnego dokumentu XUL, któ-
Znaczniki zagnieżdżone
Mamy już całkiem porządną struktu-
rę dokumentu XML do składowania in-
formacji o ulubionych ilmach, ale przy-
dałoby się ją jeszcze nieco rozbudować
o informacje na temat głównych posta-
ci ilmu. Wymaga to dodania dla każdej
postaci zestawu znaczników ją opisują-
cych – Listing 7 przedstawia przykłado-
wy kod XML.
W tym momencie pojawia się pro-
blem: nie da się takiego dokumentu zapi-
sać w postaci tablicy PHP, gdyż nie mo-
Dodawanie atrybutów
Dotychczasowe przykłady generowały
bardzo prosty kod XML, więc w kolejnym
przykładzie pora wprowadzić atrybuty.
R E K L A M A
PHP Solutions Nr 3/2006
www.phpsolmag.org
79
PEAR
XML_Serializer
Listing 8.
Tablica danych o ilmach po przebudowaniu do pracy w trybie simplexml
ry zostanie następnie zinterpretowany
przez przeglądarkę jako okno interfejsu
użytkownika z zakładkami zawierający-
mi dodatkowe informacje o ilmach po-
brane z bazy danych IMDB (Rysunek 1).
Listing 9 przedstawia kod realizujący to
zadanie.
Dane z tablicy
$movies
z poprzed-
niego przykładu są pobierane w pę-
tli
foreach
i używane do stworzenia no-
wej tablicy, na podstawie której zosta-
nie wygenerowany kod XUL. Niektóre
z opcji poznaliśmy już wcześniej, lecz
pojawia się również kilka nowych. Opcja
rootAttributes
przyjmuje argument
w postaci tablicy określającej atrybuty dla
znacznika głównego – generujemy doku-
ment XUL, więc musimy podać odpo-
wiednią dla tego formatu wartość atrybu-
tu
namespace
. Dodatkowo nadałem oknu
tytuł
Moje ulubione ilmy
i ustawiłem
dwie spacje jako ciąg używany tworzenia
wcięć w kodzie XML (to oczywiście tylko
kosmetyka, ale dzięki temu kod jest bar-
dziej czytelny).
Listing 10 przedstawia kod XML gene-
rowany przez ten przykład, a na Rysun-
ku 1 widzimy ostateczną postać interfej-
su XUL wyświetlanego przez przeglądar-
ki Mozilla.
$characters
=
array
(
array
(
'attr'
=
>
array
(
'name'
=
>
'Leeloo'
)
,
'actor'
=
>
'Milla Jovovich'
,
'imdb'
=
>
'nm0000170'
)
,
array
(
'attr'
=
>
array
(
'name'
=
>
'Korben Dallas'
)
,
'actor'
=
>
'Bruce Willis'
,
'imdb'
=
>
'nm0000246'
))
;
$movies
=
array
(
'movie'
=
>
array
(
array
(
'attr'
=
>
array
(
'name'
=
>
'Piąty Element'
)
,
'writer'
=
>
"Luc Besson"
,
'year'
=
>
"1997"
,
'imdb'
=
>
"tt0119116"
,
'character'
=
>
$characters
))
;
$options
=
array
(
'rootName'
=
>
'movies'
,
'attributesArray'
=
>
"attr"
,
'mode'
=
>
'simplexml'
)
;
Listing 9.
Kod generujący dokument z deinicją interfejsu XUL
$browser_data
=
array
(
'height'
=
>
"400"
,
'width'
=
>
"550"
)
;
foreach
(
$movies
[
'movie'
]
as
$m
){
$tabs
[
"tab"
][]
=
array
(
'label'
=
>
$m
[
'attr'
][
'name'
]
."
({
$m
[
'year'
]})
");
$url
= "
http://us.imdb.com/title/".
$m
[
'imdb'
]
;
$movie_site
=
array
(
"src"
=
>
$url
,
"id"
=
>
$m
[
'imdb'
])
;
$tab
[
'label'
]
=
$m
[
'attr'
][
'name'
]
;
$tab
[
'browser'
]
= array_merge
(
$browser_data
,
$movie_site
)
;
$tab_panels
[
'tabpanel'
][]
=
$tab
;
}
$data
=
array
(
"tabbox"
=
>
array
(
"tabs"
=
>
$tabs
,
"tabpanels"
=
>
$tab_panels
))
;
$options
=
array
(
'addDecl'
=
>
TRUE,
'rootName'
=
>
'window'
,
"defaultTagName"
=
>
'tab'
,
"scalarAsAttributes"
=
>
true,
"mode"
=
>
'simplexml'
,
'indent'
=
>
' '
,
'rootAttributes'
=
>
array
(
"xmlns"
=
>
"http://...is.only.xul"
,
"title"
=
>
"Moje ulubione ilmy"
))
;
$serializer
= &new XML_Serializer
(
$options
)
;
$status
=
$serializer
-
>
serialize
(
$data
)
;
$xml
=
$serializer
-
>
getSerializedData
()
;
header
(
'Content-type: application/vnd.mozilla.xul+xml'
)
;
echo
$xml
;
Podsumowanie
W tym krótkim artykule poznaliśmy zasa-
dy wykorzystania pakietu XML_Serializer
do tworzenia różnego rodzaju plików
XML. XML_Serializer to naprawdę świetny
pakiet i intensywnie korzystam z niego
w codziennej pracy. Istnieją wprawdzie
inne sposoby generowania kodu XML, ale
jak dotąd nie znalazłem żadnego rozwią-
zania, które sprawdzałoby się równie do-
brze i byłoby równie proste. Mam nadzieję,
że udało mi się pokazać możliwości tego
pakietu i że będzie on dla Czytelników
równie użyteczny, jak dla mnie.
n
Listing 10.
Kod XUL wygenerowany przez przykładowy skrypt
<
?xml version=
"1.0"
?
>
<
window title=
"Moje ulubione ilmy"
xmlns=
"http://www.mozilla.org/keymaster/
gatekeeper/there.is.only.xul"
>
<
tabbox
>
<
tabs
>
<
tab label=
"Piąty Element (1997)"
/
>
<
tab label=
"High Fidelity (2000)"
/
>
<
/tabs
>
<
tabpanels
>
<
tabpanel label=
"Piąty Element"
>
<
browser height=
"400"
id=
"tt0119116"
src=
"..."
width=
"550"
/
>
<
/tabpanel
>
<
tabpanel label=
"High Fidelity"
>
<
browser height=
"400"
id=
"tt0146882"
src=
"..."
width=
"550"
/
>
<
/tabpanel
>
<
/tabpanels
>
<
/tabbox
>
<
/window
>
O autorze
Aaron Wormus
programuje w PHP od
1999 r. Zajmował się tworzeniem roz-
wiązań intranetowych w Perlu i technolo-
giach pokrewnych. Aaron koncentruje się
na dostarczaniu przedsiębiorstwom wy-
sokiej jakości rozwiązań intranetowych
i wykorzystuje potęgę PHP w pracy kon-
sultanta.
Kontakt z autorem: aaron@wormus.com
80
www.phpsolmag.org
PHP Solutions Nr 3/2006
Plik z chomika:
Kapy97
Inne pliki z tego folderu:
2008.01_XSLT Czy warto zamienić HTML na XML _[XML].pdf
(316 KB)
2006.06_XML_FastCreate _[XML].pdf
(591 KB)
2006.05_XML i PHP w praktyce _[XML].pdf
(771 KB)
2006.03_Generowanie kodu XML z pakietem XML_Serializer_[XML].pdf
(501 KB)
Inne foldery tego chomika:
Ajax
Atak
Bazy Danych
Bezpieczenstwo
Biblioteka
Zgłoś jeśli
naruszono regulamin