Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Komentarz: w oryginale 15 Komentarz: Aby zachować Rozdział 10. kompletność wykładu, wstawiam między specyfikacje XLinks i XPointers opis XPath potrzebny XLinks i XPointers do XPointers. Opis ten wziąłem ze stron 643-654 z nie tłumaczonego rozdziału 13. Ten rozdział poświęcimy w całości tworzeniu połączeń między dokumentami i ich częściami specyfikacjom XLink i XPointer. W HTML mamy do dyspozycji hiperłącza, jednak autorzy XML poszli znacznie dalej tworząc specyfikacje XLink, XPointer, XPath i XBase. Niestety, omawiane tematy to kolejne obszary, w których W3C znacznie wyprzedza całą resztę świata jeszcze nie istnieją implementacje tych technologii. Microsoft, który już nieraz pośliznął się implementując standardy XML, które pózniej się zmieniały, dopiero zaczyna w Internet Explorerze XLinks i XPointers obsługiwać. W przyszłości niewątpliwie pojawią się pełne implementacje, ale na razie omawiane tu tematy są ściśle teoretyczne. W skrócie: powiązanie XLinks i XPointers Aącza XLinks opisują sposób łączenia jednego dokumentu z innym. XPointers to wskazniki określające położenie wybranego fragmentu w dokumencie, korzystają przy tym z rekomendacji XPath. Teraz w skrócie omówimy całość łączy XML. W chwili pisania specyfikacja XLink ma status proponowanej rekomendacji i datowana jest na 20 grudnia 2000 roku. Najnowszą wersję tej rekomendacji znajdziesz pod adresem Komentarz: w oryginale: szkic roboczy z 21 lutego 2000r. www.w3.org/TR/xlink. XLinks używa się do łączenia jednego dokumentu z innym, oto co W3C mówi we wstępie: W tej specyfikacji opisano Język łączy XML (XML Linking Language, XLink), która umożliwia wstawianie do dokumentów XML elementów tworzących i opisujących łącza między zasobami. Za pomocą składni XML można opisać zarówno proste łącza podobne do hiperłączy HTML, jak i łącza znacznie bardziej wyrafinowane. Oto przykład, który ma Ci nieco przybliżyć łącza XLinks. W przeciwieństwie do HTML, rolę łącza pełnić może dowolny element jego rodzaj określa się podając odpowiednią wartość atrybutu xlink:type: xlink:type="simple" xlink:show="new" xlink:href="http://www.starpowdermovies.com/reviews.xml"> Pan Blandings buduje dom swoich marzeń C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 1 2 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony)
W tym wypadku utworzyliśmy proste łącze działające podobnie jak hiperłącze HTML decyduje o tym atrybut xlink:type o wartości simple. Ustawiliśmy też atrybut xlink:show na new, co powoduje otwarcie łącza w nowym oknie. Atrybut xlink:href zawiera adres URI nowego dokumentu (adres ten może być bardzo ogólny, niekoniecznie musi mieć postać używanych dotąd adresów URL). Zaczęliśmy od łącza prostego, aby na początek pokazać coś znajomego. Oprócz prostych łączy jednokierunkowych jak to pokazane tutaj można tworzyć też łącza dwukierunkowe, a także łącza między wieloma dokumentami, a nawet zbiorami dokumentów. Można też łącza zapisywać w bazach danych łączy nazywanych bazami łączy. XLinks umożliwiają łączenie konkretnego dokumentu, ale często taka dokładność wyboru nie jest wystarczająca. W tym wypadku w sukurs przychodzą XPointers umożliwiające wskazanie miejsca w dokumencie nawet bez modyfikowania tego dokumentu w celu wstawiania tam jakiegokolwiek znacznika. W celu wskazania jakiegoś miejsca w dokumencie XPointers korzystają ze specyfikacji XPath. XPath pozwala wskazać węzeł dokumentu XML za pomocą wyrażeń takiego typu, jak pokazane niżej: /child::*[position()=126]/child::*[position()=first()] Obecnie XPointers mają status rekomendacji proponowanej i opublikowane zostały 8 stycznia 2001 roku. Najnowszą wersję specyfikacji XPointer znajdziesz pod adresem www.w3.org/TR/xptr. Komentarz: wg stanu na chwilę tłumaczenia Oto jak W3C omawia XPointers: W specyfikacji tej zdefiniowano Język wskazników XML (XML Pointer Language, XPointer) używany jako podstawa identyfikatorów fragmentów zasobów dostępnych przez URI, takich jak text/xml, application/xml, text/xml-external-parsed-entity czy application/xml-external-parsed-entity. XPointer oparty jest na Języku ścieżek XML (XML Path Language, XPath) i obsługuje adresowanie poszczególnych części dokumentów XML. Umożliwia badanie struktury dokumentów hierarchicznych i wybieranie poszczególnych części na podstawie różnych cech, takich jak typy elementów, wartości atrybutów, treść tekstowa czy położenie względne. Wprawdzie XPointers bazują na XPath, ale rozszerzają składnię XPath, co zostanie w tym rozdziale omówione. Aby dodać wskaznik XPointer do adresu URI, wystarczy za tym adresem umieścić znak # (używany w HTML do zakładek) i dopisać xpointer() w nawiasach podając wyrażenie XPath. Oto przykład: xlink:type="simple" xlink:show="new" xlink:href="http://www.starpowdermovies.com/reviews.xml# xpointer(/child::*[position()=126]/child::*[position()=first()])"> Pan Blandings buduje dom swoich marzeń
Tyle tytułem wstępu do XLinks i XPointers. Obie specyfikacje omówimy dalej w tym rozdziale, omówimy też XBase oraz krótko XPath. Komentarz: dodałem p. uwaga na początku rozdziału 2 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Zmienność XML Trzeba zdawać sobie sprawę z tego, że specyfikacje XLink, XPointer i XBase, podobnie jak inne fragmenty XML nie mające jeszcze statusu rekomendacji, mogą się zmieniać. Opisywane specyfikacje są już bliskie stania się rekomendacjami, więc zmiany względem opisu zamieszczonego w tej książce nie powinny być zbyt duże. Trzeba też pamiętać, że kiedy pojawią się implementacje tych specyfikacji, to i one mogą się nieco różnić od propozycji W3C. Wszystko o łączach XLinks Hiperłącza są bardzo ważną częścią HTML, tworzy się je za pomocą elementu A: Pan Blandings buduje dom swoich marzeń
Hiperłącza w dokumencie HTML mają albo postać tekstu zwykle podkreślonego i w innym kolorze albo postać obrazka. Kliknięte hiperłącze otwiera nowy dokument lub wybrane jego miejsce w ramce istniejącej lub w nowym oknie, może też uruchomić program JavaScript. W tabeli 10.1 zestawiono oficjalnie obowiązujące atrybuty elementu A z HTML: Tabela 10.1. Atrybuty elementu A z HTML Atrybut Opis ACCESSKEY Przypisuje klawisz skrótu do hiperłącza. CHARSET Określa kodowanie lokalizacji docelowej hiperłącza. Ustawia się zgodnie z zestawami RFC 2045 (wartość domyślna to ISO-8859-1). CLASS Określa klasę stylu dla elementu. COORDS Określa współrzędne (w pikselach) dotyczące atrybutu SHAPE definiującego obszar na mapie obszarów. DIR Określa kierunek neutralnego kierunkowo tekstu. Ustawienie LTR oznacza tekst od lewej do prawej, RTL tekst pisany od prawej do lewej. HREF Określa docelowy adres URL hiperłącza. Użyć można albo tego atrybutu, albo atrybutu NAME. HREFLANG Określa język bazowy miejsca docelowego łącza. Ustawiane zgodnie z wartościami RFC 1766. ID Określa niepowtarzalny identyfikator znacznika. LANG Służy jako język bazowy znacznika. NAME Określa nazwę zakładki, której można użyć do odwoływania się do fragmentów docelowego dokumentu. Użyć można albo tego atrybutu, albo atrybutu HREF. C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 3 4 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) REL Określa związek opisany przez hiperłącze. REV W zasadzie ma takie samo zdarzenie, jak REL, ale składnia działa w kierunku odwrotnym. SHAPE Określa typ obszaru definiowanego w znaczniku AREA. STYLE Styl typu inline wskazujący sposób prezentacji elementu. TABINDEX Ustawia kolejność łączy na stronie w przypadku poruszania się klawiszem tabulatora. TARGET Określa nazwę ramki, z którą ma być związany adres HREF. TITLE Informacja o tytule elementu. TYPE Typ MIME miejsca docelowego wskazanego w atrybucie HREF. Zestawione atrybuty umożliwiają realizację różnych funkcji, ale zawsze konieczne jest użycie elementu A, a uzyskane łącze ma typ najprostszy z możliwych: po kliknięciu powoduje przejście do nowego dokumentu lub do innej lokalizacji dokumentu bieżącego. Związki między dokumentami mogą być znacznie bardziej złożone. Mogą na przykład być potrzebne następujące funkcje: " Ustawienie łącza wskazującego 10 serwerów zapasowych i umożliwienie przeglądarce wybranie najbliższego z nich. " Połączenie całego zestawu dokumentów z uwzględnieniem podzbiorów, które będą przeszukiwane, kiedy potrzebny jest jakiś zasób. " Określenie zestawu ścieżek umożliwiających nawigację tylko między zestawem wybranych dokumentów w różnych kierunkach. Są jeszcze inne możliwości, a XLinks umożliwiają ich realizację. XLinks nie ograniczają zestawu używanych elementów do jednego A, a to oznacza, że łącza XML nie zawsze muszą mieć postać podkreślonego, niebieskiego tekstu (można je oczywiście w dowolny sposób wyróżnić). Możliwość przetworzenia na łącze dowolnego elementu jest doskonałą wiadomością, gdyż można stworzyć elementy zawsze łączące się z określonymi zasobami. Użytkownik może nawet oczekiwać, że fragment sformatowany elementem CYTAT będzie powiązany ze zródłem tego cytatu. XLinks tworzy się stosując atrybuty, a nie elementy. W szczególności atrybutu xlink:type używa się do utworzenia łącza można mu nadać jedną z wartości: simple, extended, locator, arc, resource, title lub none. Tabela 10.2. Atrybuty łączy XLinks Atrybut Opis xlink:actuate Atrybut ten określa, kiedy następuje przejście przez łącze. Może mieć wartości onLoad, onRequest lub undefined, a także inne rozpoznawane przez używane oprogramowanie. 4 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) xlink:from Atrybut określa zasób początkowy łącza. xlink:href Jest to atrybut lokalizujący, który zawiera dane umożliwiające aplikacji obsługującej łącza odnalezienie zasobu docelowego. xlink:role Tego atrybutu używa się do opisania funkcji docelowego zasobu w sposób czytelny dla komputera, a w przypadku elementów typu rozszerzonego (extended) służy jako etykieta kategorii zasobu dla reguł przejścia po elementach łukowych. Atrybut ten może być przydatny dla wyszukiwarek. xlink:show Tego atrybutu używa się do wskazania, jak ma być wyświetlany zasób docelowy. Aplikacja XLinks musi rozpoznawać następujące wartości: new (otwiera się nowy obszar wyświetlania), replace (dane aktualnie wyświetlane są zamieniane na dołączone), embed (nowy zasób jest włączany do obecnie pokazywanego) oraz undefined (oprogramowanie decyduje o sposobie wyświetlenia). xlink:title Atrybut ten opisuje funkcję zasobu łącza w sposób zrozumiały dla ludzi. xlink:to Definiuje miejsce docelowe lub zasoby końcowe. xlink:type Atrybut ten określa typ łącza XLinks, może mieć jedną z wartości: simple, extended, locator, arc, resource, title, none. Ich znaczenie opiszemy dalej. Za pomocą atrybutów XLinks można zasymulować ich działanie w przeglądarkach takich jak Internet Explorer. Jako przykład utworzymy proste łącze. Internet Explorer obsługuje atrybut onClick elementów XML. Dodamy do tego atrybutu funkcję JavaScriptu powodującą zmianę bieżącego adresu URI. W tym celu zastosujemy obiekt location:
Dołączymy jeszcze arkusz stylów xlink_example.css, aby nasze łącze wyglądało tak, jak zwykłe hiperłącza HTML. Możemy nawet spowodować, że kursor myszki w Internet Explorerze zmieni swój kształt na dłoń, jak to ma miejsce przy zwykłych łączach: LINK {color: #0000FF; text-decoration: underline; cursor: hand} Wyniki pokazano na rysunku 15.1: łącze proste XLinks zachowuje się podobnie, jak zwykłe hiperłącze HTML (oczywiście oznacza to niewykorzystanie możliwości XLinks). Kliknięcie na to łącze spowoduje, że Internet Explorer przejdzie do nowego dokumentu. C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 5 6 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Komentarz: Na rysunek należy Rysunek 10.1. nałożyć kursor dłoni; nie udaje mi się go uzyskać ani w przypadku Symulowanie użycia Alt-PrtScr, ani PrtScr. łącza prostego XLinks w Internet Explorerze Powstaje zatem pytanie, kiedy i których atrybutów języka XLink należy użyć? Wszystko zależy od rodzaju tworzonego łącza określonego atrybutem xlink:type. W zależności od tego typu niektóre atrybuty mogą być wymagane, inne pozostają opcjonalne. Zestaw obowiązujących reguł zestawiono w tabeli 10.3, gdzie poszczególnym wierszom odpowiadają różne atrybuty XLink, natomiast kolumnom odpowiadają typy łącz XLinks. Tabela 10.3. Atrybuty wymagane i opcjonalne według ustawienia xlink:type simple extended locator arc resource title type wymagany wymagany wymagany wymagany wymagany wymagany href opcjonalny pomijany wymagany pomijany pomijany pomijany role opcjonalny opcjonalny opcjonalny opcjonalny opcjonalny pomijany title opcjonalny opcjonalny opcjonalny opcjonalny opcjonalny pomijany show opcjonalny pomijany pomijany opcjonalny pomijany pomijany actuate opcjonalny pomijany pomijany opcjonalny pomijany pomijany from pomijany pomijany pomijany opcjonalny pomijany pomijany to pomijany pomijany pomijany opcjonalny pomijany pomijany Zwróć uwagę na to, że wszystkie wymienione atrybuty używają przestrzeni nazw xlink; adresem URI tej przestrzeni zawsze jest http://www.w3.org/1999/xlink, co zresztą wynikało z poprzedniego przykładu: xlink:type="simple" xlink:show="new" xlink:href="http://www.starpowdermovies.com/reviews.xml"> Pan Blandings buduje dom swoich marzeń
6 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Baza XML (XBase) Kolejną specyfikacją W3C związaną z wiązaniem dokumentów i tworzeniem łącz jest specyfikacja XBase. W chwili pisania specyfikacja ta ma status rekomendacji proponowanej i wydana została 20 grudnia 2000 roku. Bieżącą wersję tego dokumentu znajdziesz pod adresem Komentarz: stan w chwili tłumaczenia www.w3.org/TR/xmlbase. Specyfikacja ta opisuje adres bazowy URI dokumentów XML, tak jak znacznik w HTML. Tak naprawdę właśnie znacznik był powodem powstania XBase W3C chce zapewnić pełną obsługę łączy istniejących w HTML 4.0, a dopiero potem na tej podstawie tworzyć dalsze rozszerzenia. Komentarz: u autora element , W dokumencie XML odnajduje się atrybut xml:base, aby określić bazowy adres URI tego ale dalej pokazany jest atrybut. dokumentu. Pozostałe adresy w dokumencie rozwijane są względem danego adresu bazowego. Zwróć uwagę na to, że w opisywanym elemencie używana jest przestrzeń nazw xml, a nie xlink. Przestrzeń nazw xml jest w XML przestrzenią predefiniowaną, zatem aby jej użyć, nie musisz jej deklarować. Przestrzeni tej odpowiada adres URI http://www.w3.org/XML/1998/namespace. Oto przykład użycia elementu xml:base: xml:base="http://www.starpowder.com" xlink:type="simple" xlink:show="new" xlink:href="reviews.xml"> Pan Blandings buduje dom swoich marzeń
Przy użyciu wartości atrybutu xml:base adres URI atrybutu xlink:href, u nas reviews.xml, rozwijany jest jako http://www.starpowder.com/reviews.xml. W ten sposób można użyć atrybutu xml:base do podania bazowego adresu URI związanego z dokumentem (a nawet z konkretnym elementem). Deklarowanie atrybutów XLink Zwróć uwagę na to, że jeśli chcesz walidować dokumenty XML, musisz zadeklarować atrybuty XLink tak samo, jak wszystkie inne atrybuty. Do poprzedniego przykładu można użyć następującej DTD:
xmlns:xlink CDATA #IMPLIED xml:base CDATA #IMPLIED xlink:type CDATA #IMPLIED xlink:href CDATA #IMPLIED xlink:show CDATA #IMPLIED xlink:actuate CDATA #IMPLIED xlink:title CDATA #IMPLIED> ]> xml:base="http://www.starpowder.com" xlink:type="simple" xlink:show="new" xlink:href="reviews.xml"> C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 7 8 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Pan Blandings buduje dom swoich marzeń
Można też na stałe zakodować wartości większości atrybutów XLink w tym wypadku konieczne byłoby tylko podanie wartości atrybutu xlink:href:
Z uwagi na to, że język XLink jest tak ogólny, deklarowanie elementów XLink może być dość skomplikowane elementy łącz mogą mieć elementy potomne, te mogą mieć własne elementy potomne i tak dalej. Pamiętaj, że jeśli chcesz swój dokument walidować, musisz zadeklarować wszystkie elementy XLink w DTD lub w schemacie XML. Masz już ogólne pojęcie o użyciu atrybutów XLinks, teraz przyjrzymy się im kolejno dokładniej. Zaczniemy od atrybutu najważniejszego, czyli xlink:type. Atrybut xlink:type Atrybut xlink:type określa typ tworzonego łącza XLink. Atrybut ten może mieć następujące wartości: Wartość Opis simple Tworzy łącze proste. extended Tworzy łącze rozszerzone. locator Tworzy łącze lokalizatora wskazujące zasób. arc Tworzy łuk łączący wiele zasobów i różne ścieżki przejścia pomiędzy nimi. resource Tworzy łącze zasobu, które wskazuje konkretny zasób. title Tworzy łącze tytułowe. Tego typu elementy są użyteczne na przykład wtedy, gdy czytelna dla człowieka informacja w postaci etykiety potrzebuje dalszego oznakowania lub gdy w celu zapewnienia obsługi wielu języków konieczne jest zastosowanie wielu tytułów. Tworzenie łącz prostych już widzieliśmy: xlink:type="simple" xlink:show="new" xlink:href="http://www.starpowder.com/reviews.xml# 8 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) xpointer(/child::*[position()=126]/child::*[position()=first()])"> Pan Blandings buduje dom swoich marzeń
Inne rodzaje łączy poznamy dalej w tym rozdziale. Wskazywanie zasobów atrybut xlink:href Atrybut xlink:href nazywany jest także atrybutem lokalizatorem. Atrybut ten podaje informacje umożliwiające aplikacji XLink odnalezć zdalny zasób. Definicja URI Aącza XLinks mogą być bardzo ogólne, zwykle do lokalizowania zasobów używa się adresu URI podawanego w atrybucie xlink:href. Badamy teraz sposób tworzenia łączy w XML i być może chciałbyś niejako przy okazji przyjrzeć się formalnej definicji URI znajdziesz ją pod adresem www.ics.uci.edu/pub/ietf/uri/rfc2396.txt. Widziałeś już, że w atrybucie xlink:href można podać jednocześnie adres URI oraz wskaznik XPointer: xlink:type="simple" xlink:show="new" xlink:href="http://www.starpowder.com/reviews.xml# xpointer(/child::*[position()=126]/child::*[position()=first()])"> Pan Blandings buduje dom swoich marzeń
Dalej pokażemy, jak skomplikowane mogą być wartości tego atrybutu. Opisywanie zasobów: xlink:role i xlink:title Ważnymi atrybutami XLink są xlink:role oraz xlink:title; umożliwiają one opisanie zdalnego zasobu. Oba są opcjonalne, poniżej pokazano przykład ich użycia: xlink:type="simple" xlink:show="new" xlink:role="PRZEGLD_FILMOWY[PL]" xlink:title="Opis filmu 'Pan Blandigns buduje dom swoich marzeń'" xlink:href="http://www.starpowder.com/reviews.xml# xpointer(/child::*[position()=126]/child::*[position()=first()])"> Pan Blandings buduje dom swoich marzeń
Atrybut xlink:title zawiera czytelny dla człowieka opis zasobu wskazywanego przez łącze. Chodzi o to, aby użytkownik mógł zawczasu sprawdzić, co znajduje się na drugim końcu łącza wystarczy, aby aplikacja wyświetliła tę podpowiedz. Treść atrybutu xlink:role z kolei przeznaczona jest do przetwarzania maszynowego i określa rolę łącza. Atrybut ten opisuje kategorię, do jakiej łącze należy; w naszym wypadku użyliśmy wartości PRZEGLD_FILMOWY[PL]. C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 9 10 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Jak dotąd nikt nie próbował ustandaryzować kategorii łączy w sposób podobny, jak RDF (opisany w pierwszym rozdziale) standaryzuje treści zasobów. Po prostu istnieje tu zbyt wiele możliwości. Wprawdzie wyszukiwarki mogą użyć atrybutu xlink:role do klasyfikacji łącza, ale ról używa się zwykle do definiowania łączy kierunkowych przy tworzeniu łączy rozszerzonych, które omówimy dalej. Jeśli swoje dokumenty zamierzasz walidować, atrybuty xlink:role i xlink:title musisz zadeklarować. W poniższym przykładzie użyto DTD i atrybutowi xlink:role elementu PRZEGLD_FILMOWY nadano wartość stałą PRZEGLD_FILMOWY[PL]:
xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink" xlink:type CDATA #FIXED "simple" xlink:href CDATA #REQUIRED xlink:title CDATA #IMPLIED xlink:role CDATA #FIXED "PRZEGLD_FILMOWY[PL]" > Atrybut xlink:show Atrybutu xlink:show można użyć do wskazania, jak dołączony zasób ma być wyświetlony przy aktywacji łącza. Atrybut xlink:show może mieć cztery wartości predefiniowane: Wartość Opis replace Zamienia nowym zasobem zasób bieżący w aktualnym oknie, o ile takie istnieje. new Otwiera nowy obszar wyświetlania (na przykład nowe okno) dla nowego zasobu. embed Włącza wskazywany zasób do zasobu bieżącego. undefined Informuje, że nie wymagane jest żadne konkretne ustawienie atrybutu xlink:show. Powyższe wartości atrybutu xlink:show są wartościami predefiniowanymi, ale nic nie stoi na przeszkodzie, aby stosować także swoje własne wartości. Domyślne zachowanie łączy HTML polega na przeniesieniu się do wskazywanego dokumentu i zastąpienie nim dokumentu bieżącego. Takie zachowanie można zamodelować w XLinks używając wartości replace atrybutu xlink:show: xlink:type="simple" xlink:show="replace" xlink:href="http://www.starpowder.com/reviews.xml"> Pan Blandings buduje dom swoich marzeń
Sposób traktowania tego przez aplikację zależy od użytego oprogramowania. Wprawdzie masz prawo się spodziewać, że bieżący dokument będzie zastąpiony nowym, może stać się inaczej. Na przykład aplikacja arkusza kalkulacyjnego może zastąpić wskazywanym zasobem wyświetlane dane, a nie całą zawartość bieżącego okienka. Atrybut xlink:show może też sprawić, że aplikacja użyje po uruchomieniu łącza innego arkusza stylów to, co się stanie, zależy od programisty. 10 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Jeśli wartością atrybutu xlink:show jest new, aktywacja łącza zwykle otwiera nowe okno ze wskazywanym zasobem: xlink:type="simple" xlink:show="new" xlink:href="http://www.starpowder.com/reviews.xml"> Pan Blandings buduje dom swoich marzeń
Jednak tak jak poprzednio, oprogramowanie znowu może się różnie zachować. Wartość new może po prostu oznaczać dodanie nowej kolumny do tabeli lub wyświetlenie nowego wiersza zestawienia. Do tego ustawienia podchodzić należy ostrożnie pamiętaj, że użytkownicy znający HTML nie przywykli do tego, że łącza automatycznie otwierają nowe okienka. Być może warto byłoby dodać jakieś objaśnienie, w przeciwnym wypadku tego typu zachowanie może być dla użytkownika niezrozumiałe. Podobnie należy traktować ustawienie embed. Chodzi o to, aby przy aktywacji łącza nowy zasób włączany był do dokumentu bieżącego, ale sposób realizacji tego zależeć może od aplikacji. Załóżmy, że mamy do czynienia z następującym dokumentem planety.xml:
Merkury .0553 58.65 1516 .983 43.4
Wenus .815 116.75 3716 .943 66.8
Ziemia 1 1 2107 1 128.4
Oto jak mogą wyglądać łącza do różnych planet; używamy tu także XPointers do wskazania poszczególnych planet z pliku planety.xml. Wartością atrybutów xlink:show jest embed:
C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 11 12 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) xlink:type="simple" xlink:show="embed" xlink:href="http://www.starpowdermovies.com/planety.xml# xpointer(/descendant::PLANETA[position()=1]"> Merkury
Po uruchomieniu wszystkich łączy z powyższego dokumentu dane z poszczególnych elementów PLANETA mogą zostać do bieżącego dokumentu włączone dając coś takiego (pamiętaj, że szczegółowa interpretacja zależy jednak od aplikacji!):
Merkury .0553 58.65 1516 .983 43.4
Wenus .815 116.75 3716 .943 66.8
Ziemia 1 1 2107 1 128.4
Atrybutowi xlink:show można też nadać wartość undefined, wtedy aplikacja może zastosować własny domyślny sposób prezentacji zasobu docelowego łącza. Zresztą zawsze trzeba mieć na uwadze, że aplikacja może pracowicie poustawiane wartości xlink:show zignorować 12 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) i zastosować własne, na przykład jeśli zastosowano wartości new, a przeglądarka nie jest w stanie obsłużyć wielu okienek. Atrybutowi xlink:show możesz także nadawać własne wartości. Na przykład podanie wartości nowy_wiersz może spowodować wyświetlenie danych w nowym wierszu tabeli. Omawiany atrybut może też powiedzieć nieco o formacie dokumentu, a nie o sposobie jego wyświetlenia stać się tak może, jeśli podasz jako wartość nazwę arkusza stylów. Możesz też przypisać temu atrybutowi kod JavaScriptu powodujący uruchomienie wartości atrybutu xlink:show w chwili aktywacji łącza. Nie zapominaj o zadeklarowaniu atrybutu xlink:show w przypadku walidacji dokumentów. Deklaracja ta w DTD może wyglądać na przykład tak:
xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink" xlink:type CDATA #FIXED "simple" xlink:href CDATA #REQUIRED xlink:show (new | replace | embed | undefined) #IMPLIED "replace"> Atrybut xlink:actuate Atrybut xlink:actuate pozwala wskazać, kiedy łącze ma być uruchamiane. Atrybut ten może mieć następujące wartości predefiniowane: Wartość Opis onRequest Aącze ma być uruchamiane na żądanie użytkownika. onLoad Aącze ma być uruchamiane podczas ładowania dokumentu lub zasobu. undefined Nie narzuca się żadnych wymagań względem chwili uruchamiania łącza. Atrybutowi temu można też nadawać własne wartości. Pierwsza wartość predefiniowana, onRequest, oznacza, że łącze ma być uruchamiane dopiero wtedy, kiedy zażąda tego użytkownik. Zwykle żądanie takie zgłaszane jest przez kliknięcie łącza myszką, jak to zresztą ustawiliśmy na początku tego rozdziału symulując działanie łącza XLinks w Internet Explorerze:
Jeśli wartość atrybutu xlink:actuate ustawisz na onLoad, łącze zostanie uruchomione już w chwili ładowania zasobu zawierającego to łącze. Możemy na przykład spowodować, aby C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 13 14 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) obrazek mapy był ładowany wraz z ładowaniem dokumentu go zawierającego zrealizujemy to następująco: xlink:type="simple" xlink:href="http://www.starpowder.com/gifs/image_map.gif" xlink:actuate="onLoad">
W końcu użycie wartości undefined oznacza, że moment uruchomienia łącza pozostawiamy aplikacji (oczywiście, jak zwykle, i tak ostateczna interpretacja atrybutu xlink:actuate zależy od aplikacji). Można jako wartości atrybutu xlink:actuate użyć własnych ustawień. Można na przykład zastosować wartości takie jak onLoadData, onShowImage czy onUnload. Jak zwykle walidacja dokumentów wymaga zadeklarowania także atrybutu xlink:actuate; w przypadku użycia DTD może to wyglądać następująco: xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink" xlink:type CDATA #FIXED "simple" xlink:href CDATA #REQUIRED xlink:show (new | replace | embed | undefined) #IMPLIED "replace" xlink:actuate (onRequest | onLoad | undefined) #IMPLIED "onRequest"> Aącza rozszerzone Zapewne łącza proste i sposób ich działania są Ci już dobrze znane, gdyż działają one dokładnie tak samo jak hiperłącza HTML. Teraz czas na zapowiedziane już wcześniej rozszerzenia dostępne w XLinks takie rozbudowane łącza noszą nazwę łączy rozszerzonych. Tego typu łącza mogą wiązać ze sobą wiele zasobów, obsługiwać różne ścieżki połączenia zasobów, ścieżki dwukierunkowe i łącza zewnętrzne. W tej chwili warto spróbować się przestawić na znacznie ogólniejszy sposób myślenia, spojrzeć na łącza jako wszystkie możliwe relacje między zasobami. Terminologia łączy rozszerzonych Omawiane tutaj idee mogą wydawać się bardzo niejasne w porównaniu z dobrze znanym działaniem tradycyjnych łączy prostych, ale pamiętaj, że W3C usiłuje umożliwić opisanie za pomocą XML wszelkich relacji między wieloma zasobami oraz opisanie działania tych relacji. Jest to naprawdę duże wyzwanie. Z formalnego punktu widzenia łącza rozszerzone są skierowanymi grafami z nazwami.1 Aączone zasoby są węzłami, a same łącza między nimi są krawędziami grafu. Ogólnie rzecz biorąc łącza rozszerzone składają się z połączeń między zbiorem zasobów. Zasoby mogą być lokalne, czyli być częścią elementu łącza rozszerzonego lub zdalne, czyli być poza elementem łącza rozszerzonego (co jednak wcale nie znaczy, że muszą należeć do innego dokumentu). Jeśli łącze nie zawiera żadnego zasobu lokalnego, nazywane jest łączem zewnętrznym. 1 Jeżeli krawędzie posiadają grot wskazujący kierunek to grafy takie nazywa się sieciami )przyp. tłum.) 14 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Sposób obsługi łączy zewnętrznych jest całkowicie zależne od aplikacji. Pokażę tutaj pewne zasady, ale tak naprawdę wszystko to są trochę zamki budowane na piasku. O ile mi wiadomo, nie istnieje obecnie żadne powszechnie dostępne oprogramowanie w pełni obsługujące łącza rozszerzone. Hipotetycznym przykładem może być system ekspertowy, w którym łącza między wieloma różnymi zasobami są uruchamiane w zależności od odpowiedzi na pytania tak/nie. Chodzi o to, że po odpowiedzi na szereg pytań system ekspertowy może zawężać zakres możliwych odpowiedzi i skierować użytkownika do zasobu, który najlepiej udzieli odpowiedzi na nawet bardzo złożone zapytania. Jak wspomniano wcześniej, zasoby należące do łącza rozszerzonego mogą być albo lokalne, albo zdalne. Zasoby lokalne same są częścią łącza rozszerzonego i zawarte są w elemencie, którego atrybut xlink:type ustawiono na resource. Zasoby zdalne z kolei znajdują się poza elementem łącza, choć nie muszą wcale znajdować się w innym dokumencie. Elementów lokalizujących używa się do wskazania zasobu zdalnego; takie elementy mają atrybut xlink:type o wartości locator. Podczas tworzenia elementu lokalizującego (lokalizatora) trzeba nadać także atrybutowi xlink:href wartość wskazującą zasób zdalny. Oto przykład łącza rozszerzonego. Aącze to zawiera pięć zasobów dwa łącza inline i trzy łącza zewnętrzne: xlink:type="extended" xlink:title="Dane planet"> Dane planet
C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 15 16 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Aącza inline to łącza, które mają atrybut xlink:type o wartości resource, a zasoby tych łącz zawarte są w elemencie łączącym. W tym wypadku takimi łączami są elementy NAZWA oraz DATA; oba zawierają zasób lokalny (w tym wypadku jest to po prostu tekst, choć może tu być także cały ciąg wzajemnie w sobie zawartych elementów). Aącza zewnętrzne naszego przykładu mają atrybut xlink:type o wartości locator. Aącza te służą do lokalizowania zasobów zewnętrznych, które mogą być w tym samym dokumencie lub w innym. W tym przykładzie wszystkie te zasoby znajdują się w innym dokumencie, planety.xml. Tak jak poprzednio walidacja dokumentów wymaga zadeklarowania używanych elementów i atrybutów. W naszym przykładzie można dodać następującą DTD:
Jak dotąd jedynie wskazywaliśmy, jakie elementy należące do łącze rozszerzonego reprezentują zasoby lokalne lub zdalne. Jednak użycie atrybutów xlink:from i xlink:to pozwala stworzenie łączy skierowanych nazywanych łukami. Tworzenie łuków przy pomocy atrybutów xlink:from i xlink:to W przypadku łączy prostych nie ma wątpliwości, gdzie należy się przenieść po uruchomieniu łącza wskazuje to atrybut xlink:href. Jednak w przypadku łączy złożonych sprawa się komplikuje jeśli na przykład chcesz uruchomić łącze pokazane w ostatnim przykładzie, gdzie powinieneś się znalezć? Mamy tu do czynienia ze wszelkiego rodzaju ścieżkami między różnymi zasobami. Każda możliwa ścieżka między każdymi dwoma zasobami nazywana jest łukiem. Auki w elementach XML reprezentowane są przez dodanie atrybutu xlink:type o wartości arc. Aby wskazać sposób działania łuku, używa się atrybutów xlink:show oraz xlink:actuate. Ważna rzecz: łuki mają także atrybuty xlink:from i xlink:to wskazujące łączone zasoby. Wartości tych atrybutów ustawia się tak, by odpowiadały atrybutom xlink:role zasobu zródłowego i docelowego. Poniżej pokazano poprzedni przykład, przy czym element NAZWA zamieniono na START oraz opisano trzy łuki: jeden z elementu START do wszystkich trzech elementów DANE_PLANETY (poszczególne łuki łączą jeden element początkowy z jednym końcowym). Auki zawarto w elementach PRZEGLD:
xlink:type="extended" xlink:title="Dane planet"> Dane planet
1 września 2001r.
xlink:type="locator" xlink:show="embed" xlink:href="http://www.starpowdermovies.com/planety.xml# xpointer(/descendant::PLANETA[position()=1]" C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 17 18 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) xlink:title="Merkury" xlink:role="Merkury">
C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 19 20 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) xlink:to="Ziemia" xlink:show="new" xlink:actuate="onRequest">
Auki nie muszą koniecznie odwoływać się do jednego tylko zasobu, jak to było w poprzednim przykładzie. Możemy też wszystkim trzem elementom DANE_PLANETY przypisać tę samą rolę DANE_PLANETY i pózniej za pomocą jednego elementu PRZEGLD zdefiniować trzy łuki: po jednym do każdego zasobu DANE_PLANETY:
xlink:type="extended" xlink:title="Dane planet"> Dane planet
Tak naprawdę można pomijać atrybuty xlink:from i xlink:to wtedy łuki tworzone są między danym elementem a elementami lokalizującymi danego łącza rozszerzonego (mogą one zawierać także elementy bez atrybutów xlink:from i xlink:to). Sposób faktycznej interpretacji atrybutów xlink:from i xlink:to zależy od aplikacji odczytującej zawierający je dokument. 20 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Aącza inline a łącza zewnętrzne Jeśli łącze nie zawiera żadnych łączonych przez się zasobów, nazywamy je łączem zewnętrznym. Możliwość oddzielenia łączy od łączonych zasobów to naprawdę duży krok naprzód (to samo było motywem zasadniczej zmiany w HTML 4.0 polegającej na stosowaniu arkuszy stylów zamiast specjalizowanych znaczników jak
; to samo dotyczy zewnętrznych modułów kodu w Internet Explorerze nazywanych zachowaniami). Użycie łączy zewnętrznych ma wiele zalet. Aącza zewnętrzne mogą znajdować się w odrębnych dokumentach nazywanych bazami łączy. Zbiór łączy zewnętrznych w bazie łączy nazywany jest zbiorem łączy. Oto przykład wszystkie łącza z tego dokumentu wskazują na zasoby do tego dokumentu nie należące, zatem dokument ten jest bazą łączy:
xlink:to="Wenus" xlink:show="new" C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 21 22 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) xlink:actuate="onRequest">
Wszystkie łączone zasoby znajdują się poza bieżącym dokumentem. Dodaliśmy łącza lokalizujące do wszystkich planet z dokumentu planety.xml oraz łuki od punktu wejściowego do poszczególnych planet. Zwykle w bazie łączy używa się trzech rodzajów łączy: łączy rozszerzonych, lokalizatorów i łuków. Nie mogą wystąpić żadne łącza typu resource. Bazy łączy podlegają takim samym regułom jak wszelkie inne dokumenty XML, wobec czego walidacja ich wymaga dodania DTD:
xlink:to="Ziemia" xlink:show="new" xlink:actuate="onRequest"> 24 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony)
Pojawia się tutaj kolejna wątpliwość: skoro łącza zewnętrzne nie są zawarte w żadnym ze wskazywanych zasobów, jak oprogramowanie ma je odnalezć? W tym wypadku specyfikacja W3C jest dość niejasna, podobnie jak w przypadku łączenia z dokumentami XML zewnętrznych arkuszy stylów. Zakłada się, że aplikacja sama będzie odpowiedzialna za odnalezienie odpowiednich baz łączy. Trzeba przyznać, że trudno sobie wyobrazić, jak aplikacja ma odnajdować bazy łączy, jeśli znaczniki i treść mają być całkowicie oddzielne, zatem nie można bazy łączy wstawić do żadnego ze wskazywanych z zasobów (to tak, jak w przypadku komentowania czyjejś pracy, kiedy nie masz dostępu do dokumentu zródłowego). Jeśli jesteś w stanie dodać w zasobie łącze do bazy łączy, W3C sugeruje zrobienie tego: w celu utworzenia w bazie łączy można użyć predefiniowanej roli xlink:external-linkbase: xmlns:xlink="http://www.w3.org/1999/xlink" xlink:role="xlink:external-linkset" xlink:href="baza_łączy.xml"/>
Komentarz: proponuję zostawić pusty wiersz Dotąd w tym rozdziale mówiliśmy o tym, że atrybutu xlink:href używa się do wskazania zasobów. Jednak możliwości są tutaj naprawdę duże: nie tylko można podać tutaj URI, ale można także użyć wskazników XPointers do wybrania konkretnych miejsc w dokumencie lub jego fragmentów. Zanim jednak przejdziemy do omawiania specyfikacji XPointer, powiedzieć należy nieco o specyfikacji XPath, która jest podstawą XPointer i bez której trudno będzie tę ostatnią zrozumieć. Komentarz: to zdanie dodałem w związku z wstawieniem Wyrażenia XPath to silne narzędzie pozwalające dobierać węzły dokumentu. Użycie XPath następnej części rozdziału nie oznacza ograniczenia się do węzła bieżącego i jego węzłów potomnych, można też wskazywać węzeł rodzica, przodków i tak dalej. Wskazywanie węzła, względem którego chcesz pracować, nazywamy w XPath określeniem osi. Komentarz: dodałem akapit sprzed tytułu rozdziału jako wprowadzający Komentarz: Fragment wstawiony z rozdziału 13 (zgodnie Zrozumieć XPath z opisem na początku rozdziału) Do wskazania w XPath węzła lub zbioru węzłów używa się ścieżki lokalizacji. Ścieżka ta z kolei składa się z jednego lub więcej kroków lokalizacji oddzielanych od siebie znakami / lub //. Jeśli ścieżka zaczyna się od /, nazywamy ją ścieżką bezwzględną, gdyż całą ścieżkę podaje się względem węzła głównego. W przeciwnym wypadku ścieżkę nazywamy względną, zaczyna się ona od bieżącego węzła nazywanego węzłem kontekstowym. Wszystko jasne? To dobrze, bo to dopiero początek. Krok lokalizacji składa się z osi, badania węzła oraz zera lub więcej predykatów. Jeśli na przykład wyrażenie ma postać child::PLANETA[position()=5], nazwą osi jest child, badanie węzła to wyrażenie PLANETA, natomiast zapis [position()=5] to predykat. Ścieżki lokalizacji składać się mogą z jednego lub więcej kroków lokalizacji, na przykład /descendant::PLANET/child::NAZWA wybiera elementy NAZWA mające rodzica C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 25 26 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) PLANETA. Najlepszym sposobem zrozumienia, jak to działa, jest obejrzenie przykładów i na następnych stronach takich przykładów będzie mnóstwo. Przyjrzymy się rodzajom obsługiwanych w XPath osi, sposobów badania węzłów i predykatów. Osie XPath W ścieżce lokalizacji XPath child::NAZWA wskazującej element NAZWA będącym dzieckiem węzła bieżącego, child (dziecko) nazywamy osią. W XPath obsługiwane są też różne inne osie i konieczna jest ich znajomość: Oś Opis ancestor Dotyczy przodków węzła kontekstowego. Przodkami są rodzice węzła kontekstowego, rodzice tych rodziców i tak dalej, aż po węzeł główny włącznie. ancestor-or-self Dotyczy węzła kontekstowego i jego przodków. attribute Dotyczy atrybutów węzła kontekstowego. child Dotyczy dzieci węzła kontekstowego. descendant Dotyczy potomków węzła kontekstowego. Potomek to dziecko, dziecko dziecka i tak dalej. descendant-or-self Dotyczy węzła kontekstowego i jego potomków. following Dotyczy wszystkich węzłów z dokumentu, do którego należy węzeł kontekstu, które znajdują się po nim. following-sibling Dotyczy wszystkich węzłów znajdujących się na tym samym poziomie co węzeł kontekstu, za tym węzłem. namespace Dotyczy węzłów przestrzeni nazw węzła kontekstu. parent Dotyczy węzła rodzica węzła kontekstowego. preceding Dotyczy wszystkich węzłów z dokumentu, do którego należy węzeł kontekstu, które znajdują się przed nim. preceding-sibling Dotyczy wszystkich węzłów znajdujących się na tym samym poziomie co węzeł kontekstu, przed tym węzłem. self Zawiera węzeł kontekstowy. Osie można wskazywać w każdym kroku lokalizacji lub ścieżce. Poniższy przykład przedstawia arkusz stylów XSL, w którym atrybutowi select elementu xsl:value-of przypisano wyrażenia XPath. Użyto osi child do poinformowania, że chodzi o wybranie węzłów dzieci węzła kontekstu, którym jest element PLANETA (dalej pokażemy zapis skrótowy pozwalający pomijać część child::):
26 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony)
W powyższych wyrażeniach osią jest child, nazwy elementów NAZWA, MASA i DZIEC są badaniami węzłów (lub testami węzłów). Badanie węzłów w XPath Jako testów węzłów można użyć nazw węzłów, można też użyć znaku * do wybrania wszystkich elementów. Na przykład wyrażenie child::*/child::NAZWA powoduje wybranie elementów NAZWA będących wnukami węzła kontekstu. Można też użyć innych testów: Test węzła Opis comment() Wybiera węzły komentarza. node() Wybiera węzły dowolnego typu. processing- Wybiera węzły instrukcji przetwarzania. W nawiasach instruction() można podać także nazwę instrukcji. text() Wybiera węzły tekstowe. Predykaty XPath Predykat należący do kroku XPath jest zapewne najciekawszą częścią tego kroku, gdyż zapewnia największą elastyczność. W predykatach można użyć wszystkiego rodzaju wyrażeń oto dopuszczalne typy: " zbiory węzłów, " logiczne, " liczbowe, " tekstowe, " wynikowe fragmenty drzewek. Teraz kolejno wszystkim rodzajom się przyjrzymy. Zbiory węzłów XPath Zbiór węzłów jak to wskazuje sama nazwa to po prostu zbiór węzłów. Wyrażenie takie jak child::PLANETA zwraca zbiór węzłów elementów PLANETA. Wyrażenie child::PLANETA/child::NAZWA zwraca listę węzłów elementów NAZWA będących dziećmi elementów PLANETA. Do wybrania ze zbioru węzła lub węzłów można użyć różnych funkcji używanych w predykatach: C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 27 28 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Funkcja Opis last() Zwraca liczbę węzłów w zbiorze. position() Zwraca położenie węzła kontekstowego w zbiorze węzła kontekstowego (zliczanie zaczyna się od 1). count(zbiór-węzłów) Zwraca liczbę węzłów w przekazanym zbiorze. Jeśli argument nie zostanie podany, zliczone zostaną węzły zbioru węzła kontekstowego. id(string ID) Zwraca zbiór węzłów zawierających element o identyfikatorze pasującym do wartości przekazanej funkcji, a jeśli elementów takich nie ma, zwraca pusty zbiór węzłów. Można podać zestaw identyfikatorów rozdzielonych spacjami, a funkcja zwróci zbiór węzłów elementów z takimi identyfikatorami. local-name(zbiór- Zwraca nazwę lokalną pierwszego węzła ze zbioru węzłów) węzłów. Pominięcie parametru powoduje uruchomienie funkcji na węzle kontekstu. namespace-uri(zbiór- Zwraca adres URI przestrzeni nazw pierwszego węzła węzłów) ze zbioru. Pominięcie parametru powoduje użycie przez funkcję węzła kontekstu. name(zbiór-węzłów) Zwraca pełną, kwalifikowaną nazwę pierwszego węzła ze zbioru. Pominięcie parametru powoduje użycie przez funkcję węzła kontekstu. Oto przykład, w którym ponumerujemy elementy dokumentu wynikowego przy użyciu funkcji position():
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Planety
28 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Oto wyniki planety z dokumentu XML zostały ponumerowane:
Planety
1. Merkury
2. Wenus
3. Ziemia
Funkcji działających na zbiorach węzłów można używać w predykatach, na przykład wyrażenie child::PLANETA[position()=last()] wybierze ostatnie dziecko PLANETA z węzła kontekstowego. Wyrażenia logiczne XPath W wyrażeniach XPath można używać także wyrażeń logicznych. Liczba uważana jest za fałsz, jeśli równa jest zeru i uważana jest za prawdę w każdym innym przypadku. Napis pusty ("") uważany jest za fałsz, wszystkie inne napisy odpowiadają prawdzie. Operatory logiczne XPath umożliwiają wyliczenie wartości typu prawda/fałsz: Operator Opis != różne < mniejsze (w dokumentach XML zapisywać należy jako <) <= mniejsze bądz równe (w dokumentach XML zapisywać należy jako <=) = równe (uwaga dla programistów języków C, C++, Java, JavaScript: nie należy używać podwójnego znaku równości) > większe >= większe bądz równe W dokumentach XML nie należy używać znaku < bezpośrednio, lecz należy używać odwołania do encji <. Poszczególne elementy wyrażenia logicznego łączyć można spójnikami and i or podobnie jak to robiliśmy w JavaScripcie i Javie. Oto przykład użycia operatora logicznego > reguła dotyczy wszystkich elementów PLANETA o numerze większym od 5:
C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 29 30 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Istnieją też funkcje true() i false() zwracające zawsze wartości odpowiednio prawdy i fałszu. Funkcji not() można użyć do odwrócenia logicznej wartości wyrażenia; poniżej wybieramy wszystkie elementy PLANETA oprócz ostatniego:
W końcu funkcja lang() zwraca wartość prawdy lub fałszu w zależności od tego, czy język węzła kontekstu (określony atrybutem xml:lang) jest taki sam, jak język przekazany tej funkcji jako parametr. Liczby w XPath Liczby w XPath zapisywane są jako zmiennoprzecinkowe liczby podwójnej precyzji (w rozdziale 10 podano nieco więcej szczegółów technicznych; formalnie rzecz biorąc liczby XPath przechowywane są w formacie zmiennoprzecinkowym podwójnej precyzji IEEE 754). W takiej postaci przechowywane są wszystkie liczby, nawet liczby całkowite jak 5 w poniższym przykładzie:
Do przetwarzania liczb można użyć kilku operatorów: Operator Działanie + dodawanie - odejmowanie * mnożenie div dzielenie (znak / zwykle oznaczający to działanie jest w XML i XPath intensywnie wykorzystywany w innych celach) mod modulo (reszta z dzielenia pierwszego argumentu przez drugi) Na przykład użycie zapisu wstawia napis 600 do dokumentu wynikowego. Przykład ten wybiera wszystkie planety, których dzień (mierzony dniami ziemskimi) podzielony przez masę (podaną w masach Ziemi) daje wynik większy od 100:
XPath obsługuje także kilka funkcji działających na liczbach: Funkcja Opis ceiling() Zwraca najmniejszą liczbę całkowitą większą od liczby 30 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) przekazanej jako parametr. floor() Zwraca największą liczbę całkowitą mniejszą od liczby przekazanej jako parametr. round() Zaokrągla przekazaną liczbę do najbliższej liczby całkowitej. sum() Zwraca sumę przekazanych funkcji liczb. W poniższym przykładzie określamy średnią masę planet z dokumentu planety.xml:
Średnia masa planet wynosi:
Napisy w XPath Napisy XPath składają się ze znaków Unicode. Istnieje wiele takich funkcji, zestawiono je w poniższej tabeli: Funkcja Opis starts-with(string Zwraca prawdę, jeśli pierwszy napis zaczyna się drugim napis1, string napisem. napis2) contains(string Zwraca prawdę, jeśli pierwszy napis zawiera drugi. napis1, string napis2) substring(string Zwraca ilość znaków z przekazanego napisu od znaku napis1, number ofset poczynając. ofset, number ilość) substring- Zwraca część napisu1 do pierwszego wystąpienia before(string napisu2. napis1, string napis2) substring- Zwraca część napisu1 od pierwszego wystąpienia after(string napis1, napisu2 poczynając. string napis2) string-length(string Zwraca liczbę znaków w napisie1. napis1) normalize- Zwraca napis1 po usunięciu spacji wiodących space(string napis1) i końcowych oraz po zamianie wszystkich ciągów kolejnych spacji na pojedyncze. translate(string Zwraca napis1 po zastąpieniu wszystkich wystąpień C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 31 32 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) napis1, string napis2 napisami napis3. napis2, string napis3) concat(string Zwraca wszystkie przekazane napisy połączone w całość. napis1, string napis2, ...) format-number(number Zwraca napis zawierający sformatowaną liczbę1, liczba1, string przy czym napis2 używany jest jako ciąg formatujący, napis2, string natomiast napis3 to opcjonalne ustawienie językowe. napis3) Ciągi formatujące są takie same, jak w metodzie Javy java.text.DecimalFormat. Wynikowe fragmenty drzewa w XPath Wynikowy fragment drzewa to część dokumentu XML nie będąca kompletnym węzłem ani kompletnym zestawem węzłów. Fragmenty takie mogą być tworzone na różne sposoby, na przykład w przypadku użycia funkcji document() podczas wskazywania czegoś w innym dokumencie. W XPath niewiele można zrobić z wynikowymi fragmentami drzewa XPath; tak naprawdę można jedynie użyć funkcji string() lub boolean() do zamiany ich odpowiednio na napis lub wartość logiczną. Przykłady wyrażeń XPath Już niezle znasz teorię XPath, teraz czas na jakieś konkretne przykłady. W poniższej tabeli podano szereg przykładów ścieżek z objaśnieniem ich działania. Zwróć uwagę na to, że w predykatach można użyć operatorów and i or do połączenia ze sobą wielu wzorców. Przykład Znaczenie child::PLANETA Zwraca elementy PLANETA będące dziećmi węzła (czyli węzła kontekstowego). child::* Zwraca wszystkie dzieci bieżącego węzła będące elementami. child::text() Zwraca wszystkie dzieci bieżącego węzła będące węzłami tekstowymi. child::node() Zwraca wszystkie dzieci bieżącego węzła niezależnie od ich typu. attribute::JEDNOSTKI Zwraca atrybut JEDNOSTKI bieżącego węzła. descendant::PLANETA Zwraca wszystkie elementy PLANETA będące dziećmi węzła kontekstu. ancestor::PLANETA Zwraca wszystkich przodków PLANETA węzła kontekstu. ancestor-or- Zwraca wszystkich przodków PLANETA węzła 32 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) self::PLANETA kontekstowego. Jeśli węzeł ten także jest typu PLANETA, także jest włączany do zbioru wyników. descendant-or- Zwraca elementy PLANETA będące potomkami węzła self::PLANETA kontekstowego. Jeśli sam węzeł kontekstu też jest typu PLANETA, jest dołączany do zbioru wyników. self::PLANETA Zwraca węzeł kontekstowy, o ile jest on elementem typu PLANETA. child::NAZWA/descend Zwraca elementy PLANETA będące potomkami ant::PLANETA elementów NAZWA będących dziećmi węzła kontekstowego. child::*/child::PLAN Zwraca wszystkie elementy PLANETA będące wnukami ETA bieżącego węzła. / Zwraca węzeł główny dokumentu (czyli rodzica elementu głównego). /descendant::PLANETA Zwraca wszystkie elementy PLANETA z dokumentu. /descendant::PLANETA Zwraca elementy NAZWA mające element PLANETA /child::NAZWA za rodzica. child::PLANETA[posit Zwraca trzecie dziecko typu PLANETA węzła kontekstu. ion()=3] child::PLANETA[posit Zwraca ostatnie dziecko PLANETA węzła kontekstowego. ion() = last()] /descendant::PLANETA Zwraca trzeci element PLANETA z dokumentu. [position() = 3] child::PLANETY/child Zwraca trzeci element NAZWA czwartego elementu ::PLANETA[position() PLANETA z elementu PLANETY. = 4]/child::NAZWA[posi tion() = 3] child::PLANETA[posit Zwraca dzieci PLANETA węzła kontekstu znajdujące się ion() > 3] za trzecim takim elementem. preceding- Zwraca drugi wstecz element NAZWA znajdujący się sibling::NAZWA[posit na tym samym poziomie, co bieżący węzeł. ion() = 2] child::PLANETA[attri Zwraca dzieci PLANETA węzła kontekstowego mające bute::KOLOR="CZERWON atrybut KOLOR o wartości CZERWONY. Y"] child::PLANETA[attri Zwraca trzecie dziecko PLANETA węzła kontekstu mające ute::KOLOR="CZERWONY atrybut KOLOR o wartości CZERWONY. "][position() = 3] C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 33 34 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) child::PLANETA[posit Zwraca trzecie dziecko PLANETA węzła kontekstu tylko ion() = wtedy, gdy dziecko to ma atrybut KOLOR o wartości 3][attribute::KOLOR CZERWONY. = "CZERWONY"] child::MASA[child::N Zwraca dzieci MASA węzła kontekstu mające dzieci AZWA = "WENUS"] NAZWA zawierające napis WENUS. child::PLANETA[child Zwraca dzieci PLANETA węzła kontekstu mające dzieci ::NAZWA] NAZWA. child::*[self::NAZWA Zwraca dzieci węzła kontekstu typów NAZWA oraz MASA. or self::MASA] child::*[self::NAZWA Zwraca pierwsze dziecko typu NAZWA lub MASA węzła or kontekstu. self::MASA][position () = first()] Jak widać w powyższej tabeli, niektóre formy są całkiem złożone, a ich zapis jest niepokojąco długi. Istnieje jednak także skrócona forma zapisu XPath. Składnia skrócona XPath Istnieje szereg skrótów zapisu składni XPath. Oto odpowiednie reguły: Wyrażenie Skrót self::node() . parent::node() .. child::dziecko dziecko attribute::dziecko @dziecko /descendant-or- // self::node()/ Można też skracać zapis wyrażeń predykatów, na przykład [position() = 3] można zapisać jako [3], [position() = last()] jako [last()] i tak dalej. Użycie składni skróconej wyrażeń XPath znacznie ułatwia ich użycie. Oto przykłady zapisu skróconych wyrażeń XPath: Przykład Znaczenie PLANETA Zwraca elementy PLANETA będące dziećmi węzła (czyli węzła kontekstowego). * Zwraca wszystkie dzieci bieżącego węzła będące elementami. text() Zwraca wszystkie dzieci bieżącego węzła będące węzłami tekstowymi. @JEDNOSTKI Zwraca atrybut JEDNOSTKI bieżącego węzła. 34 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) @* Zwraca wszystkie atrybuty węzła kontekstu. PLANETA[3] Zwraca trzecie dziecko PLANETA węzła kontekstu. PLANETA[first()] Zwraca pierwsze dziecko PLANETA węzła kontekstu. */PLANETA Zwraca wszystkie wnuki (dzieci dzieci) PLANETA węzła kontekstu. /PLANETY/PLANETA[3]/ Zwraca drugi element NAZWA trzeciego elementu NAZWA[2] PLANETA elementu PLANETY. //PLANETA Zwraca wszystkich potomków PLANETA węzła głównego. PLANETY//PLANETA Zwraca wszystkich potomków PLANETA elementów PLANETY będących dziećmi węzła bieżącego. //PLANETA/NAZWA Zwraca elementy NAZWA mające rodzica PLANETA. . Zwraca węzeł kontekstu. .//PLANETA Zwraca elementy PLANETA będące potomkami węzła kontekstowego. .. Zwraca rodzica węzła kontekstowego. ../@JEDNOSTKI Zwraca atrybut JEDNOSTKI rodzica węzła kontekstowego. PLANETA[NAZWA] Zwraca dzieci PLANETA węzła kontekstowego mające dzieci NAZWA. PLANETA[NAZWA="Wenus Zwraca dzieci PLANETA węzła kontekstowego mające "] dzieci NAZWA z treścią Wenus. PLANETA[@JEDNOSTKI=" Zwraca dzieci PLANETA węzła kontekstu mające atrybut dzień"] JEDNOSTKI o wartości dzień. PLANETA[6][@JEDNOSTK Zwraca szóste dziecko PLANETA węzła kontekstu, jeśli I="dzień"] ma ono atrybut JEDNOSTKI o wartości dzień. To samo wyrażenie można zapisać też jako PLANETA[@JEDNOSTKI="dzień"][6]. PLANETA[@KOLOR and Zwraca wszystkie dzieci PLANETA węzła kontekstu @JEDNOSTKI] mające atrybuty KOLOR oraz JEDNOSTKI. Oto przykład, w którym użyto właśnie zapisu skróconego opisując węzły sąsiadujące z węzłem elementów PLANETA:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 35 36 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony)
Komentarz: Koniec wstawionego fragmentu z rozdziału 13 Wszystko o XPointers Na początku tego rozdziału przyglądaliśmy się łączu, w którym użyto wskaznika XPointer do wybrania konkretnego elementu z dokumentu: xlink:type="simple" xlink:show="new" xlink:href="http://www.starpowdermovies.com/reviews.xml# xpointer(/child::*[position()=126]/child::*[position()=first()])"> Pan Blandings buduje dom swoich marzeń
Część XPointer wygląda tutaj tak: xpointer(/child::*[position()=126]/child::*[position()=first()])"> Wskaznik ten jest dołączany do adresu URI za znakiem #. Być może zauważyłeś, że powyższe wyrażenie XPointer jest bardzo podobne do wyrażeń XPath i nie dzieje się tak bez powodu XPointers korzystają z nieco rozszerzonych XPath. XPointers mają wszystkie możliwości, które mają ścieżki XPath. Oznacza to między innymi, że XPointers mogą składać się z kroków lokalizacji wskazujących jakieś konkretne miejsce w dokumencie mimo, że do samego dokumentu nic nie trzeba dodawać. Można też użyć funkcji id() wskazującej konkretne elementy, pozwala to wskazywać elementy o zadanym atrybucie typu ID. Jednak z uwagi na to, że XPointers specyfikację XPath rozszerzają, istnieją pewne różnice. Największa różnica polega na tym, że jako że użytkownik może wybierać części dokumentów za pomocą myszy, XPointers umożliwiają wybieranie punktów i zakresów, a nie tylko zwykłych węzłów XPath. Punkt to punkt: jakieś miejsce w dokumencie. Zakres składa się z całego kodu XML znajdującego się między dwoma punktami, może zawierać elementy i tekst. Aby obsłużyć punkty i zakresy, w XPointers ideę węzłów rozszerzono do pojęcia lokalizacji. Każda lokalizacja jest węzłem XPath, punktem lub zakresem. Wobec tego zbiory węzłów stają się w specyfikacji XPointer zbiorami lokalizacji. Wskazniki XPointers tworzy się tak samo, jak tworzy się ścieżki XPath. XPointers składają się ze ścieżek lokalizacji podzielonych na kroki lokalizacji porozdzielane od siebie ukośnikami /. Na krok lokalizacji składa się oś, test węzła oraz zero lub więcej predykatów: oś::test_węzła[predykat] 36 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Na przykład w wyrażeniu child::PLANETA[position() = 5] osią jest child, PLANETA to test węzła, a [position() = 5] jest predykatem. Ścieżki lokalizacji mogą składać się z jednego lub więcej kroków lokalizacji, na przykład ścieżka descendant::PLANETA/child::NAZWA składa się z dwóch kroków i wybiera elementy NAZWA mające rodziców PLANETA. Możliwości XPointers są większe niż możliwości XPath, wobec tego przyjrzymy się teraz wszystkim częściom składowym: osiom, badaniu węzłów i predykatom, ale tym razem już z punktu widzenia XPointers. Osie XPointers Oś Opis ancestor Dotyczy przodków węzła kontekstowego. Przodkami są rodzice węzła kontekstowego, rodzice tych rodziców i tak dalej, aż po węzeł główny włącznie. ancestor-or-self Dotyczy węzła kontekstowego i jego przodków. attribute Dotyczy atrybutów węzła kontekstowego. child Dotyczy dzieci węzła kontekstowego. descendant Dotyczy potomków węzła kontekstowego. Potomek to dziecko, dziecko dziecka i tak dalej. descendant-or-self Dotyczy węzła kontekstowego i jego potomków. following Dotyczy wszystkich węzłów z dokumentu, do którego należy węzeł kontekstu, które znajdują się po nim. following-sibling Dotyczy wszystkich węzłów znajdujących się na tym samym poziomie co węzeł kontekstu, ale za tym węzłem. namespace Dotyczy węzłów przestrzeni nazw węzła kontekstu. parent Dotyczy węzła rodzica węzła kontekstowego. preceding Dotyczy wszystkich węzłów z dokumentu, do którego należy węzeł kontekstu, które znajdują się przed nim. preceding-sibling Dotyczy wszystkich węzłów znajdujących się na tym samym poziomie co węzeł kontekstu, ale przed tym węzłem. self Zawiera węzeł kontekstowy. Wprawdzie osie są takie same jak w XPath, ale inne są już możliwości badania węzłów. Testowanie węzłów XPointer Oto testy węzłów, których można używać w XPointers: C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 37 38 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Test węzła Opis * Wybiera dowolne elementy. node() Wybiera węzły dowolnego typu. text() Wybiera węzły tekstowe. comment() Wybiera węzły komentarza. processing- Wybiera węzły instrukcji przetwarzania. W nawiasach instruction() można podać także nazwę instrukcji. point() Wybiera punkt w zasobie. range() Wybiera zakres w zasobie. Szczególną uwagę zwróć na dwa ostatnie testy: point() i range(). Odpowiadają one dwóm nowym konstrukcjom wprowadzonym w XPointers, czyli punktom i zakresom, omówimy je dokładnie pod koniec tego rozdziału. Aby rozszerzyć XPath o punkty i zakresy, w specyfikacji XPointer wprowadzono pojęcie lokalizacji, która może być węzłem XPath, punktem lub zakresem. Jednak testy węzłów nadal pozostają testami węzłów, nie są zamieniane na testy lokalizacji. Kiedy mówimy o testach węzłów, to w XPointers ich definicja została tak rozszerzona, aby mogły one objąć także testy punktów i zakresów. Ta pewna niekonsekwencja zapewne zostanie ostatecznie wyjaśniona w ostatecznej postaci rekomendacji XPointer. Predykaty XPointer XPointers obsługują takie same typy wyrażeń jak XPaths: " zbiory węzłów, " logiczne, " liczbowe, " napisów, " fragmenty drzewek wynikowych. Jak to już objaśniano, istnieją specjalne funkcje dostosowane do użycia z poszczególnymi rodzajami wyrażeń, poza tym w XPointers istnieją dodatkowe funkcje pozwalające rzutować części wyrażeń na odpowiednie typy XPath: boolean(), string(), text() oraz number(). Dodano też funkcję unique() umożliwiającą sprawdzenie, czy XPointer wskazuje pojedynczą lokalizację, a nie wiele lub żadną. W XPointers dodano też funkcje zwracające zbiory lokalizacji, funkcje te zostaną teraz omówione. Funkcje zbiorów lokalizacji XPointer W XPointers zdefiniowano cztery funkcje zwracające zbiory lokalizacji: 38 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Funkcja Opis id() Zwraca element o zadanym identyfikatorze. root() Zwraca zbiór lokalizacji składający się jedynie z węzła głównego. here() Zwraca zbiór lokalizacji składający się jedynie z lokalizacji bieżącej. origin() Ma takie samo znaczenie jak here(), ale ta funkcja używana jest w łączach zewnętrznych. Funkcja id() jest tą samą funkcją, co zdefiniowana w XPath zwraca wszystkie lokalizacje o zadanym identyfikatorze. Funkcja root() działa dokładnie tak jak znak /: odwołuje się do węzła głównego (nie jest to węzeł elementu głównego, ale węzeł dotyczący całego dokumentu). Funkcja root() nie należy obecnie do specyfikacji XPath, ale występuje w XPointer. Nie wiadomo jeszcze, czy pozostanie tam także w ostatecznej rekomendacji. Funkcja here() odnosi się do elementu bieżącego. Jest użyteczna, gdyż XPointers zwykle znajdują się w węzłach tekstowych lub wartościach atrybutów i konieczne może być odwołanie się do bieżącego elementu, a nie do bieżącego węzła. Załóżmy na przykład, że chcesz odwołać się do drugiego od końca elementu NAZWA znajdującego się na tym samym poziomie, co element zawierający XPointer zastosować należy wtedy wyrażenie: here()/preceding-sibling::NAZWA[position() = 2] Funkcja origin() jest bardzo podobna do here(), ale używa jej się w łączach zewnętrznych, które należeć mogą do innego dokumentu, z którego łącze zostało uruchomione. Może to być bardzo przydatne, jeśli samo łącze należy do bazy łączy i nie należy odwoływać się do elementu, do którego łącze należy, ale do pierwotnego elementu, z którego zostało uruchomione. W XPointers można używać również składni skróconej. Poniżej podano kilka przykładów opartych na pliku planety.xml:
Merkury .0553 58.65 1516 .983 43.4
Wenus .815 116.75 3716 .943 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 39 40 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) 66.8
Ziemia 1 1 2107 1 128.4
Oto obiecane przykłady wskazników XPointers. Zwróć uwagę, że można używać znanych z XPath nawiasów kwadratowych powodujących wybranie konkretnej lokalizacji ze zbioru lokalizacji. Przykład Znaczenie PLANETA Zwraca elementy PLANETA będące dziećmi węzła (czyli węzła kontekstowego). * Zwraca wszystkie dzieci bieżącego węzła będące elementami. text() Zwraca wszystkie dzieci bieżącego węzła będące węzłami tekstowymi. @JEDNOSTKI Zwraca atrybut JEDNOSTKI bieżącego węzła. @* Zwraca wszystkie atrybuty węzła kontekstu. PLANETA[3] Zwraca trzecie dziecko PLANETA węzła kontekstu. PLANETA[first()] Zwraca pierwsze dziecko PLANETA węzła kontekstu. */PLANETA Zwraca wszystkie wnuki (dzieci dzieci) PLANETA węzła kontekstu. /PLANETY/PLANETA[3]/ Zwraca drugi element NAZWA trzeciego elementu NAZWA[2] PLANETA elementu PLANETY. //PLANETA Zwraca wszystkich potomków PLANETA węzła głównego. PLANETY//PLANETA Zwraca wszystkich potomków PLANETA elementów PLANETY będących dziećmi węzła bieżącego. //PLANETA/NAZWA Zwraca elementy NAZWA mające rodzica PLANETA. . Zwraca węzeł kontekstu. .//PLANETA Zwraca elementy PLANETA będące potomkami węzła kontekstowego. .. Zwraca rodzica węzła kontekstowego. ../@JEDNOSTKI Zwraca atrybut JEDNOSTKI rodzica węzła 40 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) kontekstowego. PLANETA[NAZWA] Zwraca dzieci PLANETA węzła kontekstowego mające dzieci NAZWA. PLANETA[NAZWA="Wenus Zwraca dzieci PLANETA węzła kontekstowego mające "] dzieci NAZWA z treścią Wenus. PLANETA[@JEDNOSTKI=" Zwraca dzieci PLANETA węzła kontekstu mające atrybut dzień"] JEDNOSTKI o wartości dzień. PLANETA[6][@JEDNOSTK Zwraca szóste dziecko PLANETA węzła kontekstu, jeśli I="dzień"] ma ono atrybut JEDNOSTKI o wartości dzień. To samo wyrażenie można zapisać też jako PLANETA[@JEDNOSTKI="dzień"][6]. PLANETA[@KOLOR and Zwraca wszystkie dzieci PLANETA węzła kontekstu @JEDNOSTKI] mające atrybuty KOLOR oraz JEDNOSTKI. W XPath można wybierać jedynie dane na poziomie węzła. Jest to wystarczające, kiedy używa się oprogramowania obsługującego XML jako zbiór węzłów, na przykład w przypadku przekształceń XSL, ale czasem to za mało. Na przykład użytkownik używający wyświetlonego dokumentu XML może kliknąć myszką jakiś punkt lub wybrać zakres dokumentu (takie obszary nie muszą się zaczynać ani kończyć na granicach węzłów, mogą zawierać różne drzewka i ich fragmenty). W celu zapewnienia dokładniejszej kontroli nad danymi XML w XPointers udostępniono punkty i zakresy. Użycie punktów XPointer Zgodnie ze specyfikacją XPointer do zdefiniowania punktu potrzebne są dwie rzeczy: węzeł oraz indeks całkowita liczba dodatnia lub zero. Węzeł stanowi odniesienie dla punktu, indeks określa, jak daleko punkt jest od swojego odniesienia. Powstaje jednak pytanie: w czym mierzyć indeks? W znakach czy w węzłach? Istnieją dwa rodzaje węzłów i w obu z nich indeks wylicza się inaczej. Punkty węzłowe Kiedy węzeł odniesienia może mieć węzły dzieci (czyli jest węzłem elementu lub węzłem głównym), nazywamy go punktem węzłowym. Indeks punktu węzłowego mierzony jest węzłami potomnymi. Indeks takiego punktu nie może być większy od liczby dzieci węzła odniesienia. Jeśli użyje się indeksu zero, punkt znajdzie się bezpośrednio przed węzłami dziećmi. Indeks 5 oznacza umieszczenie punktu zaraz za piątym węzłem dzieckiem. W przypadku punktów węzłowych można użyć osi: węzły sąsiadujące punktu to dzieci węzła odniesienia znajdujące się przed i za punktem. Same punkty jednak nie mają dzieci. C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 41 42 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Punkty znakowe Jeśli węzeł odniesienia nie może zawierać węzłów potomnych, a tylko tekst, indeks wyrażany jest w znakach. Punkty tego typu nazywamy punktami znakowymi. Indeks punktów znakowych musi być nieujemną liczbą całkowitą oraz musi być nie większy niż długość tekstu w węzle. Jeśli indeks jest zerem, punkt znajduje się tuż przed pierwszym znakiem. Indeks 5 wskazuje punkt znajdujący się zaraz za piątym znakiem. Punkty znakowe nie mają węzłów sąsiadujących ani dzieci. Na przykład element DOKUMENT można potraktować jako węzeł odniesienia w dokumencie następującym: Witamy!
W tym wypadku mamy siedem punktów znakowych, po jednym przed każdym znakiem. Punkt znakowy o indeksie 0 znajduje się tuż przed pierwszym znakiem W, o indeksie 1 przed i i tak dalej. Warto pamiętać, że w specyfikacji XPointer zestawy kolejnych spacji zbijane są w jedną spację. Punktów nie można też umieszczać wewnątrz etykiet początkowych i końcowych, instrukcji przetwarzania ani komentarzy czy jakichkolwiek innych znaczników. Tworzenie punktów W celu utworzenia punktu użyć należy w predykacie funkcji start-point(), na przykład tak: start-point()[position()=10] Oto przykład: załóżmy, że chcemy umieścić punkt tuż przed literą e w słowie Merkury w elemencie NAZWA:
Merkury .0553 58.65 1516 .983 43.4
. . . Możemy użyć następującego wyrażenia: xpointer(/PLANETY/PLANETA[1]/NAZWA/text()/start- point()[position()=1]) Analogicznie sięgnięcie przed cyfrę 6 w tekście 58.65 w elemencie DZIEC wymagać będzie wyrażenia: xpointer(/PLANETY/PLANETA[1]/DZIEC/text()/start- point()[position()=3]) 42 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Użycie zakresów XPointer Zakresy można tworzyć za pomocą dwóch punktów: początkowego i końcowego, byle tylko oba znajdowały się w jednym dokumencie i by punkt początkowy nie był za punktem końcowym (jeśli oba punkty są takie same, mówimy o zakresie zdegenerowanym). Zakres to wszystkie struktury XML między punktem początkowym a końcowym. Zakres nie musi być zamkniętym fragmentem dokumentu, może na przykład rozciągać się między różnymi poddrzewkami dokumentu. Jedyne, czego się wymaga, to aby oba punkty były w tym samym dokumencie. Tworzenie zakresów W celu utworzenia zakresu używa się dwóch ścieżek lokalizacji rozdzielonych słowem kluczowym to zamknięte w funkcji xpointer(). Oto przykład zakresu zawierającego całe słowo Merkury z dokumentu planety.xml: xpointer(/PLANETY/PLANETA[1]/NAZWA/text()/start- point()[position()=0] to /PLANETY/PLANETA[1]/NAZWA/text()/start- point()[position()=7]) Z kolei utworzenie zakresu zawierającego cały tekst z wartością promienia Merkurego, czyli 1516, będzie miał postać: xpointer(/PLANETY/PLANETA[1]/PROMIEC/text()/start- point()[position()=0] to /PLANETY/PLANETA[1]/PROMIEC/text()/start- point()[position()=4]) Funkcje zakresu Specyfikacja XPointer opisuje funkcje obsługujące zakresy: Funkcja Opis range-to(zbiór- Pobiera lokalizacje i zwraca zakres całkowicie je lokalizacji) obejmujący. Na przykład lokalizacja elementu jest przekształcana na zakres przez zwrócenie rodzica elementu jako węzła odniesienia, punktu początkowego jako liczby sąsiadów elementu poprzedzającego oraz punktu końcowego jako punktu o jeden większego od punktu początkowego. Innymi słowy funkcja ta ma wiązać ze sobą lokalizacje i zakresy. range-inside(zbiór- Zwraca zakres lub zakresy obejmujące wszystkie lokalizacji) lokalizacje z podanego zbioru. Jeśli na przykład przekazana zostanie lokalizacja elementu, wynikowy zakres zawierał będzie wszystko, co jest wewnątrz elementu. start-point(zbiór- Zwraca zbiór lokalizacji zawierający punkty początkowe. lokalizacji) Punkty te są punktami początkowymi zakresów, które zawierałyby wszystkie przekazane lokalizacje. Na przykład start-point(//PLANETA[2]) zwróci punkt znajdujący się zaraz za drugim elementem C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 43 44 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) PLANETA, natomiast start-point(//PLANETA) zwróci zbiór lokalizacji punktów znajdujących się przed elementami PLANETA. end-point(zbiór- Działa tak samo jak start-point(), ale zwraca lokalizacji) punkty końcowe tych samych zakresów obejmujących przekazane lokalizacje. Użycie zakresów napisu Specyfikacje XPointer zawiera także funkcję wyszukiwania napisów string-range(). Funkcja ta zwraca zbiór lokalizacji z jednym zakresem dla każdego niezachodzącego na inne wyszukiwanego napisu. Podczas wyszukiwania uwzględniana jest wielkość liter. Można też wskazać opcjonalne argumenty indeks i długość, które określają ilość znaków po wyszukanym napisie, gdzie zakres ma się zaczynać i ile znaków ma zawierać. Oto ogólna składnia funkcji string-range(): string-range(zbiór-lokalizacji, napis, [indeks, [długość]]) Dopasowywanie do napisu pustego Napis pusty "" znaleziony zostanie bezpośrednio przed jakimkolwiek znakiem, zatem takiego wzorca można użyć do wybrania samego początku napisu. I tak poniższe wyrażenie zwraca zbiór lokalizacji zawierający zakresy obejmujące wszystkie wystąpienia słowa Saturn: string-range(/, "Saturn") Aby wybrać konkretne wystąpienie napisu ze zbioru wynikowych lokalizacji, użyć należy nawiasów kwadratowych. Poniższe wyrażenie zwróci zakres obejmujący drugie wystąpienie słowa Saturn: string-range(/, "Saturn")[2] Poniższe wyrażenie z kolei zwróci zakres obejmujący trzecie wystąpienie słowa Jowisz w elemencie NAZWA szóstego elementu PLANETA: string-range(//PLANETA[6]/NAZWA, "Jowisz")[3] Można też wskazać zakres przy użyciu argumentów indeks (od 1) i długość. Poniższe wyrażenie zwraca zakres obejmujący litery sz w trzecim wystąpieniu słowa Jowisz w elemencie NAZWA w szóstym elemencie PLANETA: string-range(//PLANETA[6]/NAZWA, "Jowisz", 5, 2)[3] Jeśli należy wskazać pojedynczy punkt, można użyć zakresu zdegenerowanego (o zerowej długości): string-range(//PLANETA[6]/NAZWA, "Jowisz", 5, 0)[3] Innym sposobem uzyskania pojedynczego punktu jest użycie funkcji start-point() zwracającej punkt początkowy zakresu: start-point(string-range(//PLANETA[6]/NAZWA, "Jowisz", 5, 2)[3]) Poniższe wyrażenie wskazuje drugi znak @ w dowolnym węzle tekstowym w dokumencie wraz z pięcioma znakami za @: string-range(/, "@", 1, 6)[2] 44 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Skrócony zapis XPointer Z uwagi na to, że tak często zdarza się odwoływać do elementów według lokalizacji lub identyfikatora, w specyfikacji XPointer przewidziano skrócone formy zapisu. Oto przykład; załóżmy, że chcemy określić lokalizację elementu DZIEC dla planety Wenus w pliku planety.xml:
Merkury .0553 58.65 1516 .983 43.4
Wenus .815 116.75 3716 .943 66.8
. . . Odwołanie będzie wyglądało strasznie: http://www.starpowdermovies.com/planety.xml# xpointer(/child::*[position()=1]/ child::*[position()=2]/child::*[position()=3]) Jak jednak wiesz już z wykładu o XPath, można zastosować wiele skrótów na przykład [position()=x] można zapisać jako [x]. W XPointers można stosować skróty jeszcze dalej idące, mianowicie można pominąć nawiasy kwadratowe i wtedy nasze wyrażenie przybierze postać: http://www.starpowdermovies.com/planety.xml#1/2/3 Kiedy widzisz zestawione w ten sposób kroki lokalizacji zapisane pojedynczymi liczbami, kroki te odpowiadają położeniu elementów. Podobnie można użyć jako kroków lokalizacji słów oznaczających wartości atrybutów typu ID elementu. Załóżmy na przykład, że element PLANETA opisujący Wenus ma identyfikator Planeta_Miłości (czyli atrybut ID został w DTD zadeklarowany jako typu ID).
Merkury .0553 58.65 1516 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc 45 46 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) .983 43.4
Wenus .815 116.75 3716 .943 66.8
. . . Teraz do elementu DZIEC opisującego Wenus możemy dostać się tak: http://www.starpowdermovies.com/planety.xml# xpointer(//child::*[id("Planeta_Miłości")]/child::*[position()=3] Także tym razem zapis skrótowy jest znacznie prostszy: http://www.starpowdermovies.com/planety.xml#Planeta_Miłości/3 W tym przykładzie użyto funkcji id(); aby jej użyć, konieczne jest deklarowanie atrybutów identyfikujących jako należących do typu ID. Jednak nie wszystkie dokumenty mają przecież DTD lub schemat XML, zatem XPointers umożliwiają określenie wzorców alternatywnych przez podanie wielu wskazników XPointers. Oto przykład złożonego zapisu: http://www.starpowdermovies.com/planety.xml# xpointer(id("Planeta_Miłości"))xpointer(//*[@id="Planeta_Miłości"]/ 3 Jeśli zawiedzie pierwszy XPointer używający funkcji id(), użyty zostanie drugi, który wyszukuje element zawierający atrybut o nazwie ID mający żądaną wartość. Jednak dopiero przyszłość pokaże, jaka część tej funkcjonalności zostanie zaimplementowana w aplikacjach. Na tym kończymy nasz wykład na temat XLinks i XPointers. Jak się mogłeś przekonać, są to narzędzia o bardzo dużych możliwościach, znacznie większych od zwykłych hiperłączy HTML. Jednak oba standardy zostały zaproponowane już kilka lat temu i nadal nie ma żadnych ich implementacji. Można mieć nadzieję, że już wkrótce się to zmieni. 46 C:\do przegrania\Książki w txt lub doc\xml - vademecum profesjonalisty\r10-01.doc