OSIOŁKOWI W ŻŁOBY DANO...



Podobne dokumenty
Perl a XML. Narzędzia informatyczne w językoznawstwie. Generowanie danych XML - Przykład. Generowanie danych XML. Perl - Przetwarzanie XML

Być może jesteś doświadczonym programistą, biegle programujesz w Javie,

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Służy do wybierania/wyszukiwania fragmentów dokumentu XML. Przypomina trochę ścieżki w systemie operacyjnym. Niech będzie dany dokument XML:

Deklaracja struktury w C++

Systemy operacyjne. Laboratorium 8. Perl find

Podstawy JavaScript ćwiczenia

Programowanie w języku Python. Grażyna Koba

Słowem wstępu. Część rodziny języków XSL. Standard: W3C XSLT razem XPath 1.0 XSLT Trwają prace nad XSLT 3.0

Programowanie w Sieci Internet Blok 2 - PHP. Kraków, 09 listopada 2012 mgr Piotr Rytko Wydział Matematyki i Informatyki

Modelowanie hierarchicznych struktur w relacyjnych bazach danych

XQTav - reprezentacja diagramów przepływu prac w formacie SCUFL przy pomocy XQuery

WYKŁAD 3 XML DOM XML DOCUMENT OBJECT MODEL CZĘŚĆ 1

Wprowadzenie do projektu QualitySpy

Podstawy programowania skrót z wykładów:

PARADYGMATY PROGRAMOWANIA Wykład 4

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Python wstęp. Michał Bereta

Extensible Markup Language (XML) Wrocław, Java - technologie zaawansowane

Języki i techniki programowania Ćwiczenia 2

4. Pliki Informacje ogólne o dostępie do plików w PHP Sprawdzanie istnienia pliku file_exists()

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Diagnostyka pamięci RAM

Zaawansowane programowanie obiektowe - wykład 5

Wykład 8: klasy cz. 4

Zaawansowany kurs języka Python

Materiały do laboratorium MS ACCESS BASIC

Ćwiczenie: JavaScript Cookies (3x45 minut)

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Obiektowy model dokumentu. Katedra Mikroelektroniki i Technik Informatycznych

Języki skryptowe - PHP. PHP i bazy danych. Paweł Kasprowski. pawel@kasprowski.pl. vl07

Zasady programowania Dokumentacja

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

LINQ TO XML. Autor ćwiczenia: Marcin Wolicki

Metody Kompilacji Wykład 1 Wstęp

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Programowanie obiektowe

Autor: Joanna Karwowska

Oracle PL/SQL. Paweł Rajba.

System plików warstwa logiczna

Programowanie obiektowe

Laboratorium 7 Blog: dodawanie i edycja wpisów

Programowanie obiektowe

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Łączenie liczb i tekstu.

Wykorzystywanie parsera DOM w programach Java i PL/SQL

Dlaczego GML? Gdańsk r. Karol Stachura

Lab 9 Podstawy Programowania

Pliki. Operacje na plikach w Pascalu

Generated by Foxit PDF Creator Foxit Software For evaluation only. System Szablonów

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Wyszukiwanie plików w systemie Windows

Zadanie polega na stworzeniu bazy danych w pamięci zapewniającej efektywny dostęp do danych baza osób.

Kopiowanie, przenoszenie plików i folderów

Rozdział 4 KLASY, OBIEKTY, METODY


Przykładowy dokument XML

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Administracja i programowanie pod Microsoft SQL Server 2000

Programowanie obiektowe i C++ dla matematyków

Bibliotek grid została stworzona aby wykorzystywać funkcje programu R ( oraz wprowadzone do programu R) do tworzenia odwzorowań typu grid oraz siatek

Wykład 9 Kolekcje, pliki tekstowe, Przykład: Notatnik

Plan. Formularz i jego typy. Tworzenie formularza. Co to jest formularz? Typy formularzy Tworzenie prostego formularza Budowa prostego formularza

Klasa 2 INFORMATYKA. dla szkół ponadgimnazjalnych zakres rozszerzony. Założone osiągnięcia ucznia wymagania edukacyjne na. poszczególne oceny

Skrypty i funkcje Zapisywane są w m-plikach Wywoływane są przez nazwę m-pliku, w którym są zapisane (bez rozszerzenia) M-pliki mogą zawierać

System operacyjny Linux

5.4. Tworzymy formularze

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

1 Moduł Inteligentnego Głośnika

LK1: Wprowadzenie do MS Access Zakładanie bazy danych i tworzenie interfejsu użytkownika

Działanie systemu operacyjnego

WYKŁAD 1 METAJĘZYK SGML CZĘŚĆ 1

Systemy operacyjne. Laboratorium 9. Perl wyrażenia regularne. Jarosław Rudy Politechnika Wrocławska 28 lutego 2017

1 Moduł Inteligentnego Głośnika 3

ZASADY PROGRAMOWANIA KOMPUTERÓW

Zaawansowane aplikacje WWW - laboratorium

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Model semistrukturalny

Użycie Visual Basic for Applications ("VBA")

Przedrostkowa i przyrostkowa inkrementacja i dekrementacja

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Baza danych sql. 1. Wprowadzenie. 2. Repozytaria generyczne

Java EE produkcja oprogramowania

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Wykład 5: Klasy cz. 3

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD

Metody Kompilacji Wykład 3

Spis treści. Rozdział 1. Aplikacje konsoli w stylu ANSI C i podstawowe operacje w Visual C

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Funkcje i instrukcje języka JavaScript

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Instrukcja instalacji PHP-Hypercachera Refresher Standard oraz PHP-Hypercachera Refresher GZIP na Twojej witrynie

Argumenty wywołania programu, operacje na plikach

Lekcja 10. Uprawnienia. Dołączanie plików przy pomocy funkcji include() Sprawdzanie, czy plik istnieje przy pmocy funkcji file_exists()

Platformy programistyczne:.net i Java L ABORATORIUM 7,8: HACKATHON - JTTT

Ciekawym rozwiązaniem służącym do obsługi zdarzeń dla kilku przycisków w ramach jednej aktywności może być następujący kod:

Transkrypt:

Porównanie parserów XML-a OSIOŁKOWI W ŻŁOBY DANO... XML jest obecnie najpopularniejszym formatem wymiany danych. Język posiada szeroki wachlarz metod jego obsługi. W tym miesiącu w dziale a omówimy zalety i wady najpopularniejszych modułów XML, aby pomóc podjąć decyzję wyboru najlepiej dopasowanego do potrzeb użytkownika. Wdziedzinie przetwarzania dokumentów XML z pewnością trzyma się swojego motta: jest więcej niż jeden sposób, aby to zrobić. Mamy naprawdę duży wybór modułów do obsługi XML-a. Przeanalizujemy różne metody podejścia tych modułów, wykorzystując przykład przedstawiony na Rysunku 1. Ten plik zawiera dwa rekordy typu <cd> zagnieżdżone w znaczniku <result>. Każdy z tych rekordów składa się ze znaczników <artists> i <title>, reprezentujących odpowiednio nazwy artystów i tytuł płyty CD. W polu <artists> może być więcej niż jeden znacznik <artist>. Siła prostoty Najprostszy sposób na załadowanie struktury plików XML w u polega na wykorzystaniu modułu XML::Simple dostępnego w archiwum CPAN. Moduł ten udostępnia funkcję XMLin, która wczytuje plik lub łańcuch znaków zawierający kod XML i zapisuje je w strukturze obiektów a: w zależności od liczby artystów w znacznikach <artists> wynikowa struktura zawierająca nazwy artystów może być skalarem lub macierzą. To znacznie utrudnia pracę use XML::Simple; my $ref = XMLin ("data.xml"); Rysunek 1: Przykładowe dane XML reprezentujące bazę muzycznych płyt CD. Przykład struktury zmiennej $ref po załadowaniu naszego pliku przedstawia Rysunek 2. Warto zauważyć dwie rzeczy: Rysunek 2: Struktura danych zastosowana przez XML::Simple do przechowywania danych z Rysunku 1. 70 NUMER 20 PAŹDZIERNIK 2005 WWW.LINUX-MAGAZINE.PL

PROGRAMOWANIE z tą strukturą. Można jednak wymusić, aby parser zawsze stosował macierze dla określonego pola struktury. Służy do tego opcja ForceArray. Wywołanie XMLin ( data.xml, ForceArray => ['artist']); powoduje, że $ref->{cd}->[0]->{artists}->{artist} Rysunek 3: Struktura XML uproszczona za pomocą opcji GroupTags modułu XML::Simple. zawsze zwróci referencję macierzy, nawet gdy w źródle danych występuje tylko jeden artysta. Po drugie, składnia ->{artists}- >{artist} jest nieco niewygodna, ponieważ ->{artists} nie zawiera innych elementów niż ->{artist}. XML::Simple obsługuje Listing 1: xptitles 03 use XML::LibXML; 05 my $x = XML::LibXML->new() 06 or die "new failed"; 07 08 my $d = 09 $x->parse_file("data.xml") 10 or die "parse failed"; 12 my $titles = 13 "/result/cd/title/text()"; 15 for my $title ( 16 $d->findnodes($titles) ) { 17 print $title->tostring(), 18 "\n"; 19 } opcję GroupTags, pozwalającą programistom nieco uprościć wygenerowaną strukturę. Poniższy kod wygeneruje strukturę przedstawioną na Rysunku 3, która jest już znacznie prostsza w obsłudze. XMLin("data.xml", ForceArray => ['artist'], GroupTags => {'artists' => 'artist'}); W tej strukturze możemy zastosować na przykład prostą pętlę for wyszukującą numery seryjne płyt: for my $cd (<\@>{$ref->{cd}}) { print $cd-> {serial}, "<\\>n"; } XML::Simple ładuje cały plik XML do pamięci, co jest bardzo wygodne przy mniejszych plikach. Jeśli jednak mamy do czynienia z dość dużym plikiem XML, to podejście okaże się nieoptymalne, ponieważ może spowodować przepełnienie pamięci programu. Pokrętne ścieżki Wielbiciele zawiłych składni pokochają XPath. Moduł XML::LibXML z archiwum CPAN opiera się na bibliotece libxml2 związanej z projektem Gnome. Moduł ten pozwala zastosować znaną z XPath notację findnodes, stosowaną do wyszukiwania elementów Notacja Xpath wyszukująca zawartość tekstową wszystkich elementów <title> jest następująca /result/cd/title/text(): rozpoczynamy od korzenia dokumentu /, wspinamy się na gałąź <results>, <cd> i <title>, aby na końcu wywołać text(), co zwróci zawartość tekstową elementu. Można też alternatywnie zastosować składnię //title/text(), informującą XPath, że ma wykryć wszystkie elementy <title> niezależnie od tego, w którym miejscu hierarchii XML się znajdują. Skrypt xptitles z Listingu 1 demonstruje, że metoda findnodes() zwraca listę obiektów tekstowych, z których metoda tostring() w końcu pozwala odczytać poszukiwane wartości tekstowe. XPath potrafi nieźle rozwiązywać również trudniejsze zadania. Listing 2 prezentuje sposób odczytania wszystkich numerów seryjnych dysków CD, które w polach <artist> zawierają tekst Foo Fighters. Zastosowana w tym celu ścieżka /result/cd/artists/artist[.="foo Fighters"]/../../<\@>serial powoduje, że najpierw wspinamy się do znaczników <artist>, które są sprawdzane na obecność poszukiwanego tekstu za pomocą predykatu [.= Foo Fighters ]. Kropka określa bieżący węzeł w ścieżce. Jeśli w tym węźle zostanie odnaleziony poszukiwany tekst Foo Fighters, XPath przechodzi dwa poziomy wyżej w hierarchii../... Tutaj znajdują się węzły <cd>. Za pomocą <\@>serial pobierany jest obiekt atrybutu serial i zwracany jako wynik wywołania XPath. Listing 2 (xpserial) przedstawia cały skrypt, który z obiektu wynikowego wyciąga jego wartość (numer seryjny płyty CD) za pomocą metody value(). XPath umożliwia również zastosowanie notacji uproszczonej, lecz jeśli wystąpi problem z plikiem źródłowym, wyszukiwanie przyczyny może być dość utrudnione. Można jednak stwierdzić, że połączenie a i XPath pomimo wad jest z pewnością warte zastosowania, ponieważ daje dostęp do skutecznych technik XPath konstruowania solidnej logiki programu oraz zapenia doskonałe możliwości wyszukiwania błędów. W porównaniu z tym zastosowanie najprostszego nawet procesora XSLT wiąże się ze Listing 2: xpserial 03 use XML::LibXML; 05 my $x = XML::LibXML->new() 06 or die "new failed"; 07 08 my $d = 09 $x->parse_file("data.xml") 10 or die "parse failed"; 12 my $serials = q{ 13 /result/cd/artists/ artist[.="foo Fighters"]/ 15../../@serial 16 }; 17 18 for my $serial ( 19 $d->findnodes($serials) ) { 20 print $serial->value(), 21 "\n"; 22 } WWW.LINUX-MAGAZINE.PL NUMER 20 PAŹDZIERNIK 2005 71

moduł XML::Parser, może zainstalować moduł XML::SAX::Pure, który również można znaleźć w repozytorium CPAN. Warto pamiętać, że to rozwiązanie nie należy do najszybszych, lecz można je zainstalować bez konieczności posiadania kompilatora języka C. Instalacja modułu XML::Parser zajmuje dłuższą chwilę, poznacznie większymi problemami. XML::Parser Moduł XML::Parser implementuje bardziej klasyczny parser. Przekopuje się przez dokument XML znacznik po znaczniku i, gdy są spełnione określone warunki, wywołuje zdefiniowane przez użytkownika funkcje zwrotne (callback). Aby wyszukać numery seryjne płyt CD, w których nazwa artysty zawiera tekst Foo Fighters, należy na bieżąco kontrolować stan parsera już na etapie analizy drzewa Listing 3 xmlparse zawiera w wywołaniu Listing 3: xmlparse 03 use XML::Parser; 05 my $p = XML::Parser->new(); 06 $p->sethandlers( 07 Start => \&start, 08 Char => \&text, 09 ); 10 $p->parsefile("data.xml"); 12 my $serial; 13 my $is_artist; 15 ############################# 16 sub start { 17 ############################# 18 my ($p, $tag, %attrs) = @_; 19 20 if ( $tag eq "cd" ) { 21 $serial = $attrs{serial}; 22 } 23 24 $is_artist = 25 ( $tag eq "artist" ); 26 } 27 28 ############################# 29 sub text { 30 ############################# 31 my ( $p, $text ) = @_; 32 33 if ( $is_artist and 34 $text eq 35 "Foo Fighters" ) { 36 print "$serial\n"; 37 } 38 } konstruktora new () XML::Parser wskazanie funkcji zwrotnych dla parsera dla zdarzeń Start (gdy parser napotka otwierający znacznik XML) oraz Char (gdy parser napotka tekst pomiędzy znacznikami). Gdy parser napotka znacznik otwierający, jak <cd serial= 001 >, wywoła funkcję zwrotną start(), przekazując jej referencję parsera, nazwę znacznika oraz listę atrybutów w postaci par kluczy i wartości. W naszym przykładzie funkcji start () w drugim parametrze przekazywany jest ciąg znaków cd. Trzeci i czwarty parametr to odpowiednio ciągi znaków serial i 001. Funkcja zwrotna text () jest zdefiniowana w wierszu 29. Gdy parser znajdzie wartość tekstową, wywołuję tę funkcję z dwoma parametrami: referencją do parsera i ciągiem znaków reprezentującym znaleziony tekst. Aby parser wiedział, czy znaleziony tekst zawiera nazwę artysty (a nie inny ciąg znaków), musi śledzić swój stan, a w szczególności sprawdzić, czy przetwarzanie znajduje się wewnątrz znacznika <artist>. Jedyny sposób, aby parser mógł to stwierdzić, polega na zastosowaniu zmiennej globalnej $is_artist, której przypisywana jest wartość prawdziwa w przypadku, gdy otwierany jest znacznik <artist>. Zmienna globalna $serial wykorzystuje to samo podejście: zapisuje wartość numeru seryjnego w przypadku, gdy funkcja start() znajdzie atrybut serial znacznika <cd>. Dzięki temu funkcja print() w funkcji zwrotnej text() wypisuje prawidłowy numer seryjny aktualnie przetwarzanej płyty CD. To podejście zakłada, że każda płyta CD ma zdefiniowany atrybut <serial>, lecz tego możemy dopilnować, stosując kontrole poprawności składni bazy, na przykład za pomocą DTD. Modułu XML::Parser z reguły nie stosuje się bezpośrednio, lecz jako klasę bazową dla własnej klasy użytkownika. W rzeczywistości omówiony wcześniej XML::Simple może niejawnie wykorzystywać XML::Parser, jest to uzależnione od środowiska instalacji. Jeśli XML::Parser jest zainstalowany, lecz XML::Simple go nie wykorzystuje, można go do tego nakłonić, umieszczając w skrypcie klauzulę $XML::Simple::PREFERRED_PARSER = XML::Parser ;. W przypadku, gdy użytkownik pracuje na platformie, dla której nie jest dostępny Listing 4: htmlparse 03 use HTML::Parser; 05 my $p = HTML::Parser->new( 06 api_version => 3, 07 start_h => [ 08 \&start, "tagname, attr" 09 ], 10 text_h => [ \&text, "dtext" ], 12 xml_mode => 1, 13 ); 15 $p->parse_file("data.xml") 16 or die "Nie można przetworzyć"; 17 18 my $serial; 19 my $artist; 20 21 ############################# 22 sub start { 23 ############################# 24 my ( $tag, $attrs ) = @_; 25 26 if ( $tag eq "cd" ) { 27 $serial = 28 $attrs->{serial}; 29 } 30 31 $artist = 32 ( $tag eq "artist" ); 33 } 34 35 ############################# 36 sub text { 37 ############################# 38 my ($text) = @_; 39 40 if ($artist and 41 $text eq 42 "Foo Fighters" ) { 43 print "$serial\n"; 44 } 45 } 72 NUMER 20 PAŹDZIERNIK 2005 WWW.LINUX-MAGAZINE.PL

PROGRAMOWANIE nieważ do pracy potrzebuje działającej instalacji biblioteki expat. Aby uniknąć konieczności instalowania tych wszystkich bibliotek, można do pracy wykorzystać HTML::Parser lub inną bibliotekę dostępną w archiwum CPAN. Warunki są dwa: składnia nie może wiele się różnić i musi istnieć możliwość modyfikacji trybu xml_mode z nierestrykcyjnej analizy kodu HTML na bardziej wymagający tryb niezbędny w przypadku Kiepskie narzędzia, poprawne wyniki Jeśli przyjrzeć się skryptowi htmlparse z Listingu 4, można zauważyć, że konstruktor HTML::Parser oczekuje nieco innej składni niż jego odpowiednik w XML::Parser. Po zdefiniowaniu wersji API należy podać Listing 5: twig 03 use XML::Twig; 05 my $twig = XML::Twig->new( 06 TwigHandlers => { 07 "/result/cd/artists/artist" 08 => \&artist 09 } 10 ); 12 $twig->parsefile("data.xml"); 13 ############################# 15 sub artist { 16 ############################# 17 my ( $t, $artist ) = @_; 18 19 if ( $artist->text() eq 20 "Foo Fighters" ) { 21 my $cd = 22 $artist->parent() 23 ->parent(); 24 25 print $cd->att('serial'), 26 "\n"; 27 } 28 29 # Zwolnienie pamięci zajętej przez 30 # przetworzone drzewo 31 $t->purge(); 32 } parametry start_h i text_h, które definiują funkcje zwrotne dla znacznika otwierającego element oraz dla tekstu poza znacznikami Konstruktor określa również parametry parsera, które mają być obsłużone Rysunek 4: Wynik działania skryptu twigfilter (zmodyfikowana struktora XML) przez funkcje zwrotne: start () otrzyma nazwę otwierającego znacznika i listę atrybutów (w postaci referencji do tablicy), natomiast funkcja text () otrzyma po prostu odnaleziony tekst. Naginanie gałązki Moduł XML::Twig autorstwa Michela Rodriguez stanowi niezwykle efektywny sposób przeprowadzenia odwzorowania struktur danych XML na struktury danych a. Potrafi przetworzyć dokumenty XML tak monstrualnych rozmiarów, przy których XML::Simple po prostu nie daje rady. Dzieje się tak dzięki temu, że zamiast ładować cały plik do pamięci, XML::Twig przetwarza go małymi kawałkami. XML::Twig posiada tak wiele metod nawigacji, że określenie najwygodniejszej dla danego problemu może okazać się trudnym zadaniem. Skrypt twig z Listingu 5 wywołuje konstruktor XML::Twig::new() z parametrem Twighandlers, który powoduje, że gałąź struktury XML /result/cd/artists/artist jest odwzorowywana na funkcję obsługi artist() zdefiniowaną w wierszu 15. Gdy parser XML::Twig napotka znacznik <artist>, wywoła funkcję artist z dwoma parametrami. Pierwszym z nich jest obiekt klasy XML::Twig, drugim jest obiekt XML::Twig::Elt (najwyraźniej Elt to skrót od element ). Ten drugi parametr reprezentuje węzeł w drzewie XML, bezpośrednio do którego jest zaczepiony znacznik <artist>. Metoda text () obiektu XML::Twig::Elt zwraca tekst znajdujący się pomiędzy początkowym a końcowym znacznikiem <artist>. Jeśli tekst ten zawiera ciąg znaków Foo Fighters, wiersze 23 i 24 przejdą w hierarchii dwa poziomy w górę, wywołując dwukrotnie metodę parent(). Odszukany w ten sposób obiekt informacji o płycie CD jest następnie za pomocą metody att() odpytany o dostępność atrybutu serial, którego wartość jest następnie wypisywana. Po przetworzeniu znacznika artist w wierszu 31 jest wywoływana metoda purge(), która zwalnia pamięć wykorzystywaną przez drzewo XML do gałęzi, w której obiekt aktualnie się znajduje. XML::Twig jest wystarczająco inteligentny, aby nie usuwać bezpośrednich przodków bieżącego węzła, lecz usunie rodzeństwo, które zostało już w pełni przetworzone. Ten typ zarządzania pamięcią nie ma większego sensu przy tak małym drzewie XML jak przykładowe, lecz przy gigantycznych dokumentach może być kwestią życia lub śmierci. XML::Twig cechuje się nie tylko eleganckimi funkcjami nawigacyjnymi, skrypt może też zmieniać nazwy znaczników, wywoływać metody dynamicznie zmieniające drzewo, a nawet odrzucające jego fragmenty dla oszczędności pamięci. Weźmy na przykład skrypt twigfilter zli- Listing 6: twigfilter 03 use XML::Twig; 05 my $twig = 06 XML::Twig->new( 07 PrettyPrint => "indented"); 08 09 $twig->parsefile("data.xml") 10 or die "Błąd parsowania"; 12 my $root = $twig->root(); 13 for my $cd ( 15 $root->children('cd') ) { 16 $cd->att_to_field( 17 'serial', 'id' ); 18 $cd->first_child('artists') 19 ->delete(); 20 $cd->set_gi("compactdisc"); 21 } 22 23 $root->print(); WWW.LINUX-MAGAZINE.PL NUMER 20 PAŹDZIERNIK 2005 73

Rysunek 5: Zapytania XPath w interaktywnej powłoce xsh. stingu 6, który zastępuje składnię atrybutów serial='xxx' znacznika cd z postaci <cd serial= xxx >... </cd> na czytelniejszą postać <cd><id>xxx</id>... </cd>, usuwając przy okazji informacje o artyście. W tym celu skrypt wykorzystuje metodę root() odczytującą obiekt korzenia (<results>). Następnie metoda children() zwraca wszystkich potomków obiektu korzenia, to znaczy elementy cd. Metoda att_to_field() przekształca atrybuty serial elementów cd na samodzielne elementy id. W tym momencie metoda first_child() zwraca już tylko jeden element artist. Metoda delete() tego elementu unicestwia węzeł i usuwa go z drzewa. Na końcu metoda set_gi() (gi to skrót od generic identifier) zmienia nazwę obiektu cd powstałego w wy- niku parsowania znacznika <cd> na nazwę <CompactDisc>. Rysunek 4 przedstawia wynik działania tego skryptu. Parametr PrettyPrint konstruktora o wartości indented powoduje, że funkcja print () wywoływana w wierszu 23 wypisze reprezentację drzewa XML w estetycznie sformatowanej postaci. Moduł XML::Twig daje programistom możliwość pisania niezwykle zwartych programów. Należy jedynie poćwiczyć chwilę, aby nauczyć się odpowiednich technik pracy z tym modułem. XML::XSH Zwolennicy rozwiązań interaktywnych zainteresują się zapewne trybem powłoki xsh modułu XML::XSH. Wywołanie xsh otwiera interpreter tekstowy, w którym można wczytywać dokumenty zapisane na dysku twardym, a nawet odczytywać je bezpośrednio z WWW. Następnie można na tych załadowanych strukturach wykonywać dowolne żądania XPath. Wyniki są wypisywane na ekranie, można więc na bieżąco korygować wywoływane zapytania. Rysunek 5 przedstawia przykładową sesję powłoki: załadowanie dokumentu z dysku twardego (poleceniem open doca = data.xml ), po czym następuje wywołanie ls uruchamiające zapytanie XPath. Wynikiem tego zapytania jest jeden numer seryjny serial='002'. Przedstawiłem tu zaledwie kilka wybranych przykładów z ogromnej kolekcji modułów do obróbki formatu XML dostępnych w archiwum CPAN. XML::XPath, XML::DOM, XML::Mini, XML::SAX i XML::Grove są zaledwie przykładami nieskończonych możliwości programistów języka dotyczących obróbki dokumentów INFO [1] Listingi dla tego artykułu: http://www.linux-magazine.com/magazine/downloads/58/ [2] Podręcznik modułu XML::Twig: http://www.xmltwig.com/xmltwig/tutorial/index.html 74 NUMER 20 PAŹDZIERNIK 2005 WWW.LINUX-MAGAZINE.PL