r06-01, ## Documents ##, XML Vademecum profesjonalisty


Rozdział --> 6[Author:T] .
XML i wiązanie danych

W poprzednim rozdziale zajmowaliśmy się przetwarzaniem dokumentów w Internet Explorerze przy pomocy modelu DOM. Używaliśmy metod takich, jak firstChild, lastChild, lastSibling i tak dalej. Użycie tych metod pozwoliło sięgnąć do wszystkich danych dokumentu XML, ale traktowanie tego dokumentu jako drzewa węzłów było mylące, szczególnie jeśli zapomni się, że dane znakowe elementów także mają własne swoje węzły.

Dokumenty XML można jednak w Internet Explorerze obsługiwać też inaczej, tym właśnie zajmiemy się w tym rozdziale. Internet Explorer umożliwia odczytywanie dokumentów HTML i XML i przechowywanie ich w bazie danych. Używając metod bazy danych, które omówimy w tym rozdziale, możemy przechodzić między rekordami danych, co dla wielu programistów jest łatwiejsze od stosowania metod DOM.

Wiązanie danych w Internet Explorerze

W Internet Explorerze rozwinięto koncepcję wiązania danych. Wiązanie to umożliwia łączenie danych z dokumentów z bazą danych ADO (ActiveX Data Object) i później łatwy dostęp do tych danych. Taka technika pracy jest wygodna, gdyż dane z bazy można wysyłać jako dokumenty XML przez Internet i w miejscu przeznaczenia można je przekształcić z powrotem. Dzięki temu programiści, którym nieobce są zagadnienia baz danych, mogą skoncentrować się na dobrze znanych sobie technikach, a nie muszą uczyć się metod DOM.

Najpierw ogólnie omówimy wiązanie danych w Internet Explorerze, później zajmiemy się konkretnie dokumentami XML. Użycie wiązania danych w Explorerze składa się z dwóch etapów: najpierw używa się obiektów danych źródłowych (DSO, data source objects), potem dane wiąże się z elementami HTML strony sieciowej.

Więcej informacji o wiązaniu danych

Więcej informacji o wiązaniu danych w Internet Explorerze znajdziesz pod adresem http://msdn.microsoft.com/workshop/c-frame.htm#/workshop/author/default.asp.

Użycie obiektów danych źródłowych

W Internet Explorerze istnieją cztery obiekty danych źródłowych (DSO, Data Source Object): kontrolka Microsoft HTML (MSHTML), kontrolka danych tabelarycznych (TDC), XML DSO i wyspy danych XML. Internet Explorer obsługuje jeszcze dość wyspecjalizowany RDS DSO (DSO dostępu zdalnego do danych), który umożliwia połączenie się z aplikacjami bazodanowymi, takimi jak aplikacje SQL uruchamiane na serwerze sieciowym). Dwa DSO, mianowicie XML DSO i wyspy danych XML, umożliwiają obsługę dokumentów XML.

DSO na stronie nie są widoczne (choć, jak zobaczymy pod koniec tego rozdziału, XML DSO może wyświetlać na stronie komunikaty o stanie). DSO używa się do odczytywania dokumentu i udostępniania jego danych reszcie strony. Aby DSO był w stanie odczytać dane dokumentu, dane te muszą być odpowiednio sformatowane.

Poniżej przedstawiono dokument przykładowy, klient.html, który zawiera dane dotyczące sprzedaży detalicznej. Rejestrujemy nazwiska i identyfikatory klientów, daty zakupu, dział, z którego towar kupiono oraz nazwę towaru. Zwróć uwagę, jak za pomocą znaczników <SPAN> określono strukturę dokumentu, aby dane były czytelne dla Internet Explorera (można by użyć też innego znacznika, na przykład <DIV>). Każdemu znacznikowi z danymi przypisano atrybut ID, który określa rodzaj danych. Jak widać, stosowana technika aż się prosi o zapis w postaci XML.

<HTML>

<HEAD>

<TITLE>

Dane o klientach

</TITLE>

</HEAD>

<BODY>

Nazwisko: <SPAN ID="NAZWISKO">Charles</SPAN><BR>

ID: <SPAN ID="ID_KLIENTA">58704</SPAN><BR>

Data zakupu: Data: <SPAN ID="DATA_ZAKUPU">

2001.10.15</SPAN><BR>

Dział: <SPAN ID="DZIAŁ">Mięso</SPAN><BR>

Produkt: <SPAN ID="PRODUKT">Szynka</SPAN><BR>

Nazwisko: <SPAN ID="NAZWISKO">Franklin</SPAN><BR>

ID: <SPAN ID="ID_KLIENTA">58705</SPAN><BR>

Data zakupu: Data: <SPAN ID="DATA_ZAKUPU">

2001.10.15</SPAN><BR>

Dział: <SPAN ID="DZIAŁ">Warzywa</SPAN><BR>

Produkt: <SPAN ID="PRODUKT">Pomidory</SPAN><BR>

Nazwisko: <SPAN ID="NAZWISKO">Phoebe</SPAN><BR>

ID: <SPAN ID="ID_KLIENTA">58706</SPAN><BR>

Data zakupu: Data: <SPAN ID="DATA_ZAKUPU">

2001.10.15</SPAN><BR>

Dział: <SPAN ID="DZIAŁ">Mięso</SPAN><BR>

Produkt: <SPAN ID="PRODUKT">Indyk</SPAN><BR>

Nazwisko: <SPAN ID="NAZWISKO">Mark</SPAN><BR>

ID: <SPAN ID="ID_KLIENTA">58707</SPAN><BR>

Data zakupu: Data: <SPAN ID="DATA_ZAKUPU">

2001.10.15</SPAN><BR>

Dział: <SPAN ID="DZIAŁ">Mięso</SPAN><BR>

Produkt: <SPAN ID="PRODUKT">Wołowina</SPAN><BR>

Nazwisko: <SPAN ID="NAZWISKO">Nancy</SPAN><BR>

ID: <SPAN ID="ID_KLIENTA">58708</SPAN><BR>

Data zakupu: Data: <SPAN ID="DATA_ZAKUPU">

2001.10.15</SPAN><BR>

Dział: <SPAN ID="DZIAŁ">Mrożonki</SPAN><BR>

Produkt: <SPAN ID="PRODUKT">Brokuły</SPAN><BR>

</BODY>

</HTML>

Najbardziej typowym sposobem obsługi danych sformatowanych w postać dokumentu HTML jest użycie DSO MSHTML, tego obiektu tutaj użyjemy. DSO odczytuje dokument taki jaki pokazano wyżej i przekształca go na zbiór rekordów. Każdy rekord z tego zbioru pochodzi z elementów HTML lub XML, których użyto do przechowywania danych. Oto przykładowy rekord HTML:

Nazwisko: <SPAN ID="NAZWISKO">Charles</SPAN><BR>

ID: <SPAN ID="ID_KLIENTA">58704</SPAN><BR>

Data zakupu: Data: <SPAN ID="DATA_ZAKUPU">

2001.10.15</SPAN><BR>

Dział: <SPAN ID="DZIAŁ">Mięso</SPAN><BR>

Produkt: <SPAN ID="PRODUKT">Szynka</SPAN><BR>

Rekord ten ma pięć pól: NAZWISKO, ID_KLIENTA, DATA_ZAKUPU, DZIAŁ i PRODUKT. Zbiór rekordów wygląda jak tablica rekordów - kiedy pracujesz z konkretnym rekordem, możesz sięgać do jego poszczególnych pól. Aby na przykład sprawdzić, co kupił Charles, wystarczy odnaleźć opisujący go rekord i sprawdzić wartość jego pola PRODUKT.

Używając znacznika <OBJECT> można utworzyć obiekt DSO MSHTML i powiązać go z plikiem klient.html. Obiekt ten nazwiemy dsoKlient:

<OBJECT ID="dsoKlient" DATA="klient.html" HEIGHT="0" WIDTH="0">

</OBJECT>

DSO odczyta i zinterpretuje plik klient.html, przekształci go na zbiór danych ADO (tak naprawdę Internet Explorer używa zbioru tylko do odczytu, ADOR). DSO zawiera na raz dane jednego tylko rekordu, rekord ten jest rekordem bieżącym. Do nawigacji po zbiorze można używać wbudowanych metod obiektu DSO, najpopularniejsze z nich to moveFirst, moveLast, moveNext i movePrevious - odpowiednio: skok do pierwszego rekordu, skok do rekordu ostatniego, następny i poprzedni rekord. Aby wyświetlić dane z DSO, trzeba je powiązać z elementami HTML.

Wiązanie danych z elementami HTML

Tak naprawdę niewiele elementów HTML w Internet Explorerze obsługuje właściwości, które umożliwiają wiązanie danych z DSO. Do wiązania używa się atrybutów DATASRC i DATAFLD. Atrybut DATASRC jako wartość otrzymuje nazwę obiektu DSO, natomiast DATAFLD - nazwę pola danych, które ma być związane z elementem, wtedy element HTML wyświetli dane z bieżącego rekordu. Stosując metody moveFirst, moveLast, moveNext i movePrevious można pokazać pozostałe rekordy ze zbioru.

Jeśli na przykład powiążemy pole tekstowe z DSO dsoKlient z polem danych NAZWISKO, kontrolka przy pierwszym załadowaniu danych wyświetli napis Charles. Wywołanie metody moveNext spowoduje, że rekordem bieżącym stanie się drugi rekord ze zbioru, a w polu tekstowym wyświetlony zostanie napis Franklin.

Oto zestawienie elementów HTML z wyszczególnieniem, co daje ustawienie atrybutów DATASRC i DATAFLD:

Element

Co jest wiązane z danymi

A

Właściwość href; niemożliwa jest modyfikacja danych.

APPLET

Właściwość param; modyfikacja danych jest możliwa.

BUTTON

Właściwość value; niemożliwa jest modyfikacja danych.

DIV

Właściwości innerText oraz innerHTML; niemożliwa jest modyfikacja danych.

FRAME

Właściwość src; niemożliwa jest modyfikacja danych.

IFRAME

Właściwość src; niemożliwa jest modyfikacja danych.

IMG

Właściwość src; niemożliwa jest modyfikacja danych.

INPUT TYPE=BUTTON

Właściwość value; niemożliwa jest modyfikacja danych.

INPUT TYPE=CHECKBOX

Właściwość checked; możliwa jest modyfikacja danych.

INPUT TYPE=HIDDEN

Właściwość value; możliwa jest modyfikacja danych.

INPUT TYPE=PASSWORD

Właściwość value; możliwa jest modyfikacja danych.

INPUT TYPE=RADIO

Właściwość checked; możliwa jest modyfikacja danych.

INPUT TYPE=TEXT

Właściwość value; możliwa jest modyfikacja danych.

LABEL

Właściwość value; niemożliwa jest modyfikacja danych.

MARQUEE

Właściwości innerText i innerHTML; niemożliwa jest modyfikacja danych.

OBJECT

Właściwość objects; możliwa jest modyfikacja danych.

PARAM

Właściwość param; możliwa jest modyfikacja danych.

SELECT

Właściwość text opcji; możliwa jest modyfikacja danych.

SPAN

Właściwości innerText i innerHTML; niemożliwa jest modyfikacja danych.

TABLE

Tworzy całą tabelę; niemożliwa jest modyfikacja danych.

TEXTAREA

Właściwość value; możliwa jest modyfikacja danych.

Oprócz tego znaczniki HTML mają zdarzenia, których można użyć  przypadku wiązania ich z danymi:

Zdarzenie

Opis

onafterupdate

Zachodzi po aktualizacji danych elementu w DSO.

onbeforeunload

Zachodzi przed usunięciem strony z pamięci.

onbeforeupdate

Zachodzi przed aktualizacją danych elementu w DSO.

onerrorupdate

Zachodzi, jeśli dane DSO nie zostały zaktualizowane z powodu błędu.

Czas teraz całą tę naszą wiedzę zaprząc do pracy. Zaczniemy od dodania na stronie kontrolki MSHTML dsoKlient i połączenia tego obiektu DSO z plikiem klient.html:

<HTML>

<HEAD>

<TITLE>

Wiązanie danych za pomocą DSO MSHTML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie danych za pomocą DSO MSHTML

</H1>

<OBJECT ID="dsoKlient" DATA="klient.html"

HEIGHT="0" WIDTH="0">

</OBJECT>

.

.

.

Teraz nasz obiekt DSO powiążemy z polem tekstowym ustawiając atrybut DATASRC tego pola na wartość #dsoCutomer (Explorer wymaga poprzedzenia nazwy DSO krzyżykiem hash). Pole tekstowe może wyświetlić jednocześnie dane tylko z jednego pola danych, wskażemy pole NAZWISKO - użyjemy atrybutu DATAFLD:

<HTML>

<HEAD>

<TITLE>

Wiązanie danych za pomocą DSO MSHTML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie danych za pomocą DSO MSHTML

</H1>

<OBJECT ID="dsoKlient" DATA="klient.html"

HEIGHT="0" WIDTH="0">

</OBJECT>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="NAZWISKO" SIZE="10">

.

.

.

Teraz pole danych ID_KLIENTA powiążemy z następnym polem tekstowym. Zresztą dane z DSO można byłoby także wyświetlać bezpośrednio na stronie, bez używania pól tekstowych - należałoby obiekt DSO powiązać z elementem SPAN, jak to robimy z datą zakupu:

<HTML>

<HEAD>

<TITLE>

Wiązanie danych za pomocą DSO MSHTML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie danych za pomocą DSO MSHTML

</H1>

<OBJECT ID="dsoKlient" DATA="klient.html"

HEIGHT="0" WIDTH="0">

</OBJECT>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="NAZWISKO" SIZE="10">

<P>

ID: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="ID_KLIENTA" SIZE="5">

<P>

Data zakupu: <SPAN DATASRC="#dsoKlient"

DATAFLD="DATA_ZAKUPU"></SPAN>

.

.

.

Aby pokazać sposób wiązania z danymi innych kontrolek, pole DZIAŁ powiążemy z kontrolką SELECT, której odpowiada lista rozwijalna. DSO wskazujemy jak zwykle, ale trzeba też podać wszystkie dopuszczalne wartości tego pola za pomocą wewnętrznych elementów OPTION:

<HTML>

<HEAD>

<TITLE>

Wiązanie danych za pomocą DSO MSHTML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie danych za pomocą DSO MSHTML

</H1>

<OBJECT ID="dsoKlient" DATA="klient.html"

HEIGHT="0" WIDTH="0">

</OBJECT>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="NAZWISKO" SIZE="10">

<P>

ID: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="ID_KLIENTA" SIZE="5">

<P>

Data zakupu: <SPAN DATASRC="#dsoKlient"

DATAFLD="DATA_ZAKUPU"></SPAN>

<P>

Dział: <SELECT DATASRC="#dsoKlient"

DATAFLD="DZIAŁ" SIZE="1">

<OPTION VALUE="Mięso">Mięso

<OPTION VALUE="Warzywa">Warzywa

<OPTION VALUE="Mrożonki">Mrożonki

</SELECT>

<P>

Produkt: <SPAN DATASRC="#dsoKlient" DATAFLD="PRODUKT">

</SPAN>

.

.

.

Niejako przy okazji powiązaliśmy jeszcze pole danych PRODUKT z kolejnym elementem SPAN. Przy pierwszym załadowaniu strony pokazane zostaną wszystkie dane pierwszego rekordu ze zbioru danych - jak jednak pokazać pozostałe dane?

Trzeba udostępnić użytkownikowi metody moveFirst, moveLast, moveNext i movePrevious, aby mógł poruszać się po zbiorze rekordów; najwygodniej będzie powiązać te metody z przyciskami. Do obiektu zbioru rekordów z DSO można się odwoływać stosując zapis dsoKlient.recordset, zatem przesunięcie się do pierwszego rekordu realizowane metodą moveFirst będzie wyglądało tak: dsoKlient.recordset.moveFirst(). Oto przyciski, jakich użyjemy:

Opis przycisku

Funkcja

<<

Przejście do pierwszego rekordu.

<

Przejście do poprzedniego rekordu.

>

Przejście do następnego rekordu.

>>

Przejście do ostatniego rekordu.

Kod obsługi tych przycisków będzie wyglądał następująco:

<BUTTON ONCLICK="dsoKlient.recordset.moveFirst()">&lt;&lt;

</BUTTON>

<BUTTON ONCLICK="dsoKlient.recordset.movePrevious()">&lt;

</BUTTON>

<BUTTON ONCLICK="dsoKlient.recordset.moveNext()">&gt;

</BUTTON>

<BUTTON ONCLICK="dsoKlient.recordset.moveLast()">&gt;&gt;

</BUTTON>

Zanim jednak metod movePrevious i moveNext użyjemy, warto sprawdzić, czy rekordy poprzedni i następny w ogóle istnieją (jeśli przesuniemy się poza koniec zbioru rekordów, pokażą się puste pola). Można użyć właściwości BOF (początek zbioru danych) oraz EOF (koniec zbioru danych) obiektu recordset. Gotowy kod będzie wyglądał tak:

<HTML>

<HEAD>

<TITLE>

Wiązanie danych za pomocą DSO MSHTML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie danych za pomocą DSO MSHTML

</H1>

<OBJECT ID="dsoKlient" DATA="klient.html"

HEIGHT="0" WIDTH="0">

</OBJECT>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="NAZWISKO" SIZE="10">

<P>

ID: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="ID_KLIENTA" SIZE="5">

<P>

Data zakupu: <SPAN DATASRC="#dsoKlient"

DATAFLD="DATA_ZAKUPU"></SPAN>

<P>

Dział: <SELECT DATASRC="#dsoKlient"

DATAFLD="DZIAŁ" SIZE="1">

<OPTION VALUE="Mięso">Mięso

<OPTION VALUE="Warzywa">Warzywa

<OPTION VALUE="Mrożonki">Mrożonki

</SELECT>

<P>

Produkt: <SPAN DATASRC="#dsoKlient" DATAFLD="PRODUKT">

</SPAN>

<P>

<BUTTON ONCLICK="dsoKlient.recordset.moveFirst()">&lt;&lt;

</BUTTON>

<BUTTON ONCLICK="if (!dsoKlient.recordset.BOF)

dsoKlient.recordset.movePrevious()">&lt;

</BUTTON>

<BUTTON ONCLICK="if (!dsoKlient.recordset.EOF)

dsoKlient.recordset.moveNext()">&gt;

</BUTTON>

<BUTTON ONCLICK="dsoKlient.recordset.moveLast()">&gt;&gt;

</BUTTON>

</CENTER>

</BODY>

</HTML>

Wynik działania tej strony pokazano na rysunku 6.1. Jak widać, wyświetlane są dane z pliku klient.html; użytkownik może poruszać się po rekordach przy pomocy przycisków.

Rysunek 6.1.

Wiązanie danych w Internet Explorerze

0x01 graphic

Tyle ogólnie o wiązaniu danych i o HTML; czas zająć się tym, co tygrysy lubią najbardziej, czyli XML.

XML i wiązanie danych

Zaczniemy od przekształcenia pliku klient.html na XML. W HTML musieliśmy używać elementów SPAN z atrybutem ID, w XML po prostu tworzymy potrzebne nam elementy. Nasze dane jako XML uzyskają postać:

<?xml version="1.0" encoding="iso-8859-2"?>

<KLIENCI>

<KLIENT>

<NAZWISKO>Charles</NAZWISKO>

<ID_KLIENTA>58704</ID_KLIENTA>

<DATA_ZAKUPU></DATA_ZAKUPU>

2001.10.15

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Szynka</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Franklin</NAZWISKO>

<ID_KLIENTA>58705</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Warzywa</DZIAŁ>

<PRODUKT>Pomidory</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Phoebe</NAZWISKO>

<ID_KLIENTA>58706</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Indyk</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Mark</NAZWISKO>

<ID_KLIENTA>58707</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Wołowina</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Nancy</NAZWISKO>

<ID_KLIENTA>58708</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mrożonki</DZIAŁ>

<PRODUKT>Brokuły</PRODUKT>

</KLIENT>

</KLIENCI>

Jak widać, każdemu rekordowi odpowiada jeden element KLIENT. Można zresztą użyć dowolnej nazwy elementów, Internet Explorer i tak będzie w stanie przetworzyć dane. W poprzednim przykładzie, kiedy mieliśmy dane w postaci HTML, jako DSO używaliśmy kontrolki MSHTML, teraz mamy do wyboru wyspy danych XML lub DSO XML oparty na specjalnym aplecie dostarczanym wraz z Explorerem. Zaczniemy od użycia wysp danych.

Wiązanie pojedynczych rekordów przy użyciu --> wyspa[Author:AJ] danych XML

Aby zobaczyć sposób wiązania elementów HTML z wyspami danych XML, utworzymy nową stronę HTML, w której będziemy czytać dane z pliku klient.xml:

<HTML>

<HEAD>

<TITLE>

Wiązanie pojedynczych rekordów przy użyciu wysp danych XML

</TITLE>

</HEAD>

<XML SRC="klient.xml" ID="klienci”></XML>

.

.

.

Teraz już obiektu customers można użyć jako DSO, który można łączyć z elementami HTML, co już w tym rozdziale widzieliśmy:

<HTML>

<HEAD>

<TITLE>

Wiązanie pojedynczych rekordów przy użyciu wysp danych XML

</TITLE>

</HEAD>

<XML SRC="klient.xml" ID="klienci”></XML>

<BODY>

<CENTER>

<H1>

Wiązanie pojedynczych rekordów przy użyciu wysp danych XML

</H1>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#klienci”

DATAFLD="NAZWISKO" SIZE="10">

<P>

ID: <INPUT TYPE="TEXT" DATASRC="#klienci”

DATAFLD="ID_KLIENTA" SIZE="5">

<P>

Data zakupu: <SPAN DATASRC="#klienci”

DATAFLD="DATA_ZAKUPU"></SPAN>

<P>

Dział: <SELECT DATASRC="#klienci”

DATAFLD="DZIAŁ" SIZE="1">

<OPTION VALUE="Mięso">Mięso

<OPTION VALUE="Warzywa">Warzywa

<OPTION VALUE="Mrożonki">Mrożonki

</SELECT>

<P>

Produkt: <SPAN DATASRC="#klienci” DATAFLD="PRODUKT">

</SPAN>

.

.

.

</CENTER>

</BODY>

</HTML>

Właściwości, metody i zdarzenia DSO XML

W przykładzie z początku tego rozdziału pokazano, jak można użyć metod zbioru rekordów, takich jak moveFirst, moveLast, moveNext i movePrevious do poruszania się po tym zbiorze. Teraz wszystkie dostępne właściwości, metody i zdarzenia omówimy bardziej systematycznie. Zaczniemy od właściwości obiektu DSO XML:

Właściwość

Opis

absolutePage

Strona, na której jest bieżący rekord.

absolutePosition

Położenie bieżącego rekordu w zbiorze.

BOF

Ma wartość true, jeśli rekordem bieżącym jest pierwszy rekord.

cacheSize

Liczba rekordów ze zbioru znajdujących się lokalnie w pamięci podręcznej.

cursorLocation

Położenie kursora w zbiorze rekordów.

cursorType

Rodzaj użytego kursora bazy danych.

editMode

Wskazuje, czy przeprowadzana jest edycja.

EOF

Ma wartość true, jeśli rekord bieżący znajduje się za ostatnim rekordem zbioru.

lockType

Rodzaj użytego blokowania w bazie danych.

maxRecords

Dopuszczalna liczba rekordów, jaka może zostać zwrócona przez zapytanie.

pageCount

Liczba stron danych znajdujących się w zbiorze rekordów.

pageSize

Liczba rekordów składających się na jedną stronę.

recordCount

Liczba rekordów w zbiorze.

state

Stan zbioru rekordów (otwarty lub zamknięty).

status

Status bieżącego rekordu.

stayInSync

Wskazuje, czy hierarchiczny zbiór rekordów ma być cały czas związany ze źródłem danych.

Obiekty DSO XML zawierają następujące metody:

Metoda

Opis

addNew

Dodaje do zbioru nowy rekord.

cancel

Odwołuje żądanie wykonania oczekującego żądania Execute lub Open.

cancelUpdate

Odwołuje żądanie aktualizacji danych.

clone

Tworzy kopię zbioru rekordów.

close

Zamyka zbiór rekordów.

delete

Usuwa bieżący rekord (lub grupę rekordów).

find

Przeszukuje zbiór rekordów (jednak Internet Explorer nie obsługuje jeszcze składni języka SQL).

getRows

Odczytuje rekordy i zapisuje je w tablicy.

getString

Pobiera zbiór rekordów w postaci napisu (tekstu).

move

Zmienia pozycję bieżącego rekordu.

moveFirst, moveLast, moveNext, movePrevious

Umożliwiają poruszanie się po zbiorze rekordów.

nextRecordSet

Zeruje bieżący obiekt zbioru danych i zwraca zbiór następny. Metoda używana w przypadku hierarchicznych zbiorów rekordów.

open

Otwiera bazę danych.

requery

Ponownie uruchamia zapytanie tworzące zbiór danych.

save

Zapisuje bieżący zbiór rekordów w pliku.

supports

Wskazuje, jakie możliwości udostępnia zbiór danych. Konieczne jest przekazanie wartości typu long odpowiadającej zmiennym metodom ADO zgodnie z dokumentacją Microsoft ADO. Na przykład przekazanie wartości 0x1000400 (0x oznacza zapis szesnastkowy) zwróci true, aby poinformować, że zbiór danych udostępnia metodę addNew. Przekazanie 0x10000 da w wyniku false, gdyż zbiory danych nie zawierają metody updateBatch.

Z obiektami DSO XML związane są różne zdarzenia - przypomnij sobie, jak pokazywaliśmy w poprzednim rozdziale obsługę zdarzeń związanych z ładowaniem dokumentów XML.

Zdarzenie

Opis

onDataAvailable

Zachodzi przy każdym ładowaniu zestawu danych.

onDatasetChanged

Zachodzi przy każdej modyfikacji zbioru danych.

onDatasetComplete

Zachodzi, kiedy zbiór danych zostanie załadowany i gotów jest do użycia.

onReadyStateChange

Zachodzi, kiedy zmienia się wartość właściwości ReadyState.

onRowEnter

Zachodzi, kiedy inny rekord niż dotąd staje się rekordem bieżącym.

onRowExit

Zachodzi podczas opuszczania bieżącego rekordu.

onRowsDelete

Zachodzi przy usuwaniu rekordu.

onRowsInserted

Zachodzi przy wstawianiu rekordu.

onCellChange

Zachodzi, kiedy dane kontrolki związanej ze zbiorem się zmieniają, a kursor opuszcza daną komórkę.

Aby umożliwić użytkownikowi nawigację po zbiorze rekordów utworzonych z pliku klient.xml, dodamy te same przyciski, które znamy już z przykładu HTML i znów użyjemy metod typu klienci.recordset.moveNext() do nawigacji po tym zbiorze:

<HTML>

<HEAD>

<TITLE>

Wiązanie pojedynczych rekordów przy użyciu wysp danych XML

</TITLE>

</HEAD>

<XML SRC="klient.xml" ID="klienci”></XML>

<BODY>

<CENTER>

<H1>

Wiązanie pojedynczych rekordów przy użyciu wysp danych XML

</H1>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#klienci”

DATAFLD="NAZWISKO" SIZE="10">

<P>

ID: <INPUT TYPE="TEXT" DATASRC="#klienci”

DATAFLD="ID_KLIENTA" SIZE="5">

<P>

Data zakupu: <SPAN DATASRC="#klienci”

DATAFLD="DATA_ZAKUPU"></SPAN>

<P>

Dział: <SELECT DATASRC="#klienci”

DATAFLD="DZIAŁ" SIZE="1">

<OPTION VALUE="Mięso">Mięso

<OPTION VALUE="Warzywa">Warzywa

<OPTION VALUE="Mrożonki">Mrożonki

</SELECT>

<P>

Produkt: <SPAN DATASRC="#klienci” DATAFLD="PRODUKT">

</SPAN>

<P>

<BUTTON ONCLICK="klienci.recordset.moveFirst()">&lt;&lt;

</BUTTON>

<BUTTON ONCLICK="if (!klienci.recordset.BOF)

klienci.recordset.movePrevious()">&lt;

</BUTTON>

<BUTTON ONCLICK="if (!klienci.recordset.EOF)

klienci.recordset.moveNext()">&gt;

</BUTTON>

<BUTTON ONCLICK="klienci.recordset.moveLast()">&gt;&gt;

</BUTTON>

</CENTER>

</BODY>

</HTML>

Wynik naszej pracy można obejrzeć na rysunku 6.2: wartości pól danych zostały umieszczone w elementach HTML. Klikając przyciski nawigacyjne użytkownik może poruszać się po zbiorze danych.

Rysunek 6.2.

Użycie wiązania danych do wyświetlania dokumentu XML

0x01 graphic

Jak wynika z pokazanych wcześniej tabel, istnieje znacznie więcej możliwości nawigowania po zbiorze danych niż ich tu wykorzystaliśmy. Często na przykład wygodnie jest sięgać do pojedynczych pól rekordu. Załóżmy, że chcemy określić wartość pola ID_KLIENTA bieżącego rekordu DSO. Można to osiągnąć stosując wyrażenie klienci.recordset("ID_KLIENTA").

Zapewne zauważyłeś, o ile łatwiej jest sięgać do danych przez pola zbioru danych niż przez użycie metod DOM typu nextChild czy lastSibling. Jeśli dokument XML traktować jako bazę danych, użycie zbioru rekordów znakomicie upraszcza życie programisty.

Teraz pokażemy na przykładzie, jak sięgać do poszczególnych pól rekordów. Zorganizujemy pętlę działającą na kolejnych rekordach bazy danych (skorzystamy z pętli while, warunkiem zakończenia będzie uzyskanie przez właściwość EOF wartości true). Wyświetlać będziemy nazwisko klienta, kupiony towar i dział, w którym dokonano zakupu. Oto kod:

<HTML>

<HEAD>

<TITLE>

Dostęp do poszczególnych pól

</TITLE>

<XML ID="klient" SRC="klient.xml"></XML>

<SCRIPT LANGUAGE="JavaScript">

function viewData()

{

while (!klient.recordset.EOF) {

div1.innerHTML +=

klient.recordset("NAZWISKO") + " kupił(a) <I>" +

klient.recordset("PRODUKT") + "</I> w dziale " +

klient.recordset("DZIAŁ") + ".<BR>"

klient.recordset.moveNext()

}

}

</SCRIPT>

</HEAD>

<BODY>

<CENTER>

<H1>

Dostęp do poszczególnych pól

</H1>

</CENTER>

<FORM>

<CENTER>

<INPUT TYPE="BUTTON" VALUE="Przegląd danych"

ONCLICK="viewData()">

</CENTER>

</FORM>

<DIV ID="div1"></DIV>

</BODY>

</HTML>

Wyniki działania tego kodu pokazano na rysunku 6.3. Jak widać, zestawione i wyświetlone zostały poszczególne pola z różnych rekordów.

Rysunek 6.3.

Dostęp do pojedynczych pól

0x01 graphic

Jak dotąd mieliśmy dostęp do pojedynczych rekordów ze zbioru, można jednak oglądać od razu dane z całego dokumentu XML - dane te należy wstawić do tabeli.

Tabelaryczne wiązanie danych XML

Kiedy wiążesz zbiór danych z tabelą HTML, w tabeli tej umieścić można cały ten zbiór. Oto przykład - w tabelę wstawimy dane z pliku klient.xml. Zaczniemy od utworzenia wysp danych XML z identyfikatorem customers:

<HTML>

<HEAD>

<TITLE>

Tabelaryczne wiązanie danych - wyspy danych XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Tabelaryczne wiązanie danych - wyspy danych XML

</H1>

<XML SRC="klient.xml" ID="klienci”></XML>

.

.

.

Aby związać dane z pliku klient.xml z tabelą, wystarczy ustawić atrybut DATASRC tabeli na customers:

<HTML>

<HEAD>

<TITLE>

Tabelaryczne wiązanie danych - wyspy danych XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Tabelaryczne wiązanie danych - wyspy danych XML

</H1>

<XML SRC="klient.xml" ID="klienci”></XML>

<TABLE DATASRC="#klienci” CELLSPACING="10">

.

.

.

Rekord z pliku klient.xml zawiera pola NAZWISKO, ID_KLIENTA, DATA_ZAKUPU, DZIAŁ i PRODUKT. Pola te powiążemy z poszczególnymi komórkami tabeli w taki oto sposób:

<HTML>

<HEAD>

<TITLE>

Tabelaryczne wiązanie danych - wyspy danych XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Tabelaryczne wiązanie danych - wyspy danych XML

</H1>

<XML SRC="klient.xml" ID="klienci”></XML>

<TABLE DATASRC="#klienci” CELLSPACING="10">

<THEAD>

<TR>

<TH>Nazwisko</TH>

<TH>ID klienta</TH>

<TH>Data zakupu</TH>

<TH>Dział</TH>

<TH>Produkt</TH>

</TR>

</THEAD>

<TBODY>

<TR>

<TD>

<SPAN DATAFLD="NAZWISKO"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="ID_KLIENTA"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="DATA_ZAKUPU"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="DZIAŁ"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="PRODUKT"></SPAN>

</TD>

</TR>

</TBODY>

</TABLE>

</CENTER>

</BODY>

</HTML>

Wyniki pokazano na rysunku 6.4; dane z pliku klient.xml zostały wyświetlone w postaci tabeli.

Rysunek 6.4.

Wiązanie danych z tabelą w Internet Explorerze

0x01 graphic

Istnieje jeszcze jeden obiekt DSO, którego można użyć do dokumentów XML w Internet Explorerze - DSO XML.

Wiązanie pojedynczych rekordów za pomocą DSO XML

Poczynając od wersji 4 Internet Explorera Microsoft włączył DSO XML przeznaczony do korzystania z XML. Obiekt ten jest nieco dziwny, gdyż nie jest wewnętrznym obiektem Explorera, ale jest apletem Javy. Aplet ten można włączać w stronę i obiekt DSO XML tworzyć w elemencie APPLET:

<APPLET

CODE="com.ms.xml.dso.XMLDSO.class"

ID="IDENTYFIKATOR"

WIDTH="0"

HEIGHT="0"

MAYSCRIPT="true">

<PARAM NAME="URL" VALUE="AdresURLStronyXML">

</APPLET>

Stosując znacznik <PARAM> przekazujemy apletowi parametr, stosując zaś atrybut ID znacznika <APPLET> określamy nazwę DSO.

W następnym przykładzie użyjemy DSO XML łącząc go z plikiem klient.xml. Aby powiązać nasz plik XML z elementami HTML, zaczniemy od dodania apletu XML do strony sieciowej - wywołamy DSO dsoKlient i przekażemy mu jako parametr adres URL dokumentu:

<HTML>

<HEAD>

<TITLE>

Wiązanie pojedynczych rekordów przy pomocy DSO XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie pojedynczych rekordów przy pomocy DSO XML

</H1>

<APPLET

CODE="com.ms.xml.dso.XMLDSO.class"

ID="dsoKlient"

WIDTH="0"

HEIGHT="0"

MAYSCRIPT="true">

<PARAM NAME="URL" VALUE="klient.xml">

</APPLET>

.

.

.

To już właściwie wszystko. DSO udostępnia obiekt zbioru danych tak, jak to się dzieje w przypadku wysp danych XML, możemy zatem wiązać elementy HTML tak, jak poprzednio:

<HTML>

<HEAD>

<TITLE>

Wiązanie pojedynczych rekordów przy pomocy DSO XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie pojedynczych rekordów przy pomocy DSO XML

</H1>

<APPLET

CODE="com.ms.xml.dso.XMLDSO.class"

ID="dsoKlient"

WIDTH="0"

HEIGHT="0"

MAYSCRIPT="true">

<PARAM NAME="URL" VALUE="klient.xml">

</APPLET>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="NAZWISKO" SIZE="10">

<P>

ID: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="ID_KLIENTA" SIZE="5">

<P>

Data zakupu: <SPAN DATASRC="#dsoKlient"

DATAFLD="DATA_ZAKUPU"></SPAN>

<P>

Dział: <SELECT DATASRC="#dsoKlient"

DATAFLD="DZIAŁ" SIZE="1">

<OPTION VALUE="Mięso">Mięso

<OPTION VALUE="Warzywa">Warzywa

<OPTION VALUE="Mrożonki">Mrożonki

</SELECT>

<P>

Produkt: <SPAN DATASRC="#dsoKlient" DATAFLD="PRODUKT">

</SPAN>

.

.

.

Można znowu użyć metod obiektu zbioru danych, takich jak moveNext, do poruszania się między rekordami; metody te znowu możemy powiązać z przyciskami:

<HTML>

<HEAD>

<TITLE>

Wiązanie pojedynczych rekordów przy pomocy DSO XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie pojedynczych rekordów przy pomocy DSO XML

</H1>

<APPLET

CODE="com.ms.xml.dso.XMLDSO.class"

ID="dsoKlient"

WIDTH="0"

HEIGHT="0"

MAYSCRIPT="true">

<PARAM NAME="URL" VALUE="klient.xml">

</APPLET>

Nazwisko: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="NAZWISKO" SIZE="10">

<P>

ID: <INPUT TYPE="TEXT" DATASRC="#dsoKlient"

DATAFLD="ID_KLIENTA" SIZE="5">

<P>

Data zakupu: <SPAN DATASRC="#dsoKlient"

DATAFLD="DATA_ZAKUPU"></SPAN>

<P>

Dział: <SELECT DATASRC="#dsoKlient"

DATAFLD="DZIAŁ" SIZE="1">

<OPTION VALUE="Mięso">Mięso

<OPTION VALUE="Warzywa">Warzywa

<OPTION VALUE="Mrożonki">Mrożonki

</SELECT>

<P>

Produkt: <SPAN DATASRC="#dsoKlient" DATAFLD="PRODUKT">

</SPAN>

<P>

<BUTTON ONCLICK="dsoKlient.recordset.moveFirst()">&lt;&lt;

</BUTTON>

<BUTTON ONCLICK="if (!dsoKlient.recordset.BOF)

dsoKlient.recordset.movePrevious()">&lt;

</BUTTON>

<BUTTON ONCLICK="if (!dsoKlient.recordset.EOF)

dsoKlient.recordset.moveNext()">&gt;

</BUTTON>

<BUTTON ONCLICK="dsoKlient.recordset.moveLast()">&gt;&gt;

</BUTTON>

</CENTER>

</BODY>

</HTML>

Działanie tej strony pokazano na rysunku 6.5. Aplet --> DSO XML[Author:T] działa zgodnie z oczekiwaniami, ale w niczym nie zmienia to faktu, że aplet ten jest obiektem zewnętrznym względem Explorera, co sugeruje, że Microsoft wcześniej czy później może porzucić dalszy jego rozwój na rzecz wysp XML.

Rysunek 6.5.

Wiązanie pojedynczych rekordów przy pomocy DSO XML

0x01 graphic

Tak jak wyspy danych XML, tak i DSO XML można wiązać z tabelami.

Tabelaryczne wiązanie danych za pomocą DSO XML

Wiązać XML DSO z tabelami jest równie łatwo, jak wiązać z tabelami wyspy danych. W poniższym przykładzie pokażemy, jak to działa. Powiążemy z tabelą dane z klient.xml, wyświetlimy jednocześnie wszystkie pola poszczególnych rekordów:

<HTML>

<HEAD>

<TITLE>

Wiązanie danych DSO XML z tabelami

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Wiązanie danych DSO XML z tabelami

</H1>

<APPLET CODE="com.ms.xml.dso.XMLDSO.class""

ID="klienci”

WIDTH="0" HEIGHT="0"

MAYSCRIPT="true">

<PARAM NAME="URL" VALUE="klient.xml">

</APPLET>

<TABLE DATASRC="#klienci” CELLSPACING="10">

<THEAD>

<TR>

<TH>Nazwisko</TH>

<TH>ID klienta</TH>

<TH>Data zakupu</TH>

<TH>Dział</TH>

<TH>Produkt</TH>

</TR>

</THEAD>

<TBODY>

<TR>

<TD>

<SPAN DATAFLD="NAZWISKO"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="ID_KLIENTA"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="DATA_ZAKUPU"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="DZIAŁ"></SPAN>

</TD>

<TD>

<SPAN DATAFLD="PRODUKT"></SPAN>

</TD>

</TR>

</TBODY>

</TABLE>

</CENTER>

</BODY>

</HTML>

Teraz można już na rysunku 6.6 obejrzeć wyniki naszej pracy.

Rysunek 6.6.

Wiązanie danych DSO XML z tabelą

0x01 graphic

XML i dane hierarchiczne

Jedną z najciekawszych cech współczesnych baz danych jest możliwość tworzenia hierarchicznych rekordów zbiorów, w których pojedyncze rekordy mogą zawierać całe zbiory nowych rekordów. Dokumenty XML to idealny sposób zapisu takich hierarchicznych zbiorów, gdyż bez problemu można zawierać jeden zestaw elementów w innym.

Oto przykład. Dodajemy do danych klientów z pliku klient.xml dane o dostawach i wszystko zapisujemy w nowym dokumencie, dostawy.xml.

<?xml version="1.0" encoding="iso-8859-2"?>

<KLIENCI>

<KLIENT>

<NAZWISKO>Charles</NAZWISKO>

<REKORD>

<ID_KLIENTA>58704</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Szynka</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>7.90 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>5.80 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Franklin</NAZWISKO>

<REKORD>

<ID_KLIENTA>58705</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Warzywa</DZIAŁ>

<PRODUKT>Pomidory</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>12.00 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>11.80 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Phoebe</NAZWISKO>

<REKORD>

<ID_KLIENTA>58706</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Indyk</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>22.00 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>34.00 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Mark</NAZWISKO>

<REKORD>

<ID_KLIENTA>58707</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Wołowina</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>15.80 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>27.90 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Nancy</NAZWISKO>

<REKORD>

<ID_KLIENTA>58708</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mrożonki</DZIAŁ>

<PRODUKT>Brokuły</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>7.90 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>11.80 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

</KLIENCI>

W pokazywanym przykładzie element REKORD zawiera dwa elementy DOSTAWA, a te z kolei zawierają po jednym elemencie DATA i SUMA. Obiekt DSO nie może potraktować wielu tak umieszczonych rekordów jako rekordu pojedynczego, gdyż spowodowałoby to powstanie w jednym rekordzie kilku pól o tej samej nazwie. W Internet Explorerze można w takiej sytuacji użyć hierarchicznego zbioru rekordów, w których każdemu elementowi DOSTAWA odpowiada jeden podzbiór rekordów.

Powstaje zatem kwestia, jak w hierarchicznej bazie danych można się odwoływać do takich podzbiorów? Jak na przykład odwołać się do elementów DOSTAWA zawartych w poszczególnych elementach REKORD? Stosuje się odwołanie do nowego zbioru rekordów, na przykład REKORD.DOSTAWA. Wyrażenie to oznacza odwołanie do zbioru rekordów będącego dzieckiem elementów DOSTAWA.

Jak zwykle łatwiej wszystko to zrozumieć na przykładzie. Opiszemy powiązanie danych pliku dostawy.xml z tabelą i wyświetlanie danych o poszczególnych dostawach. Zaczynamy od powiązania tabeli z wyspą danych XML i wyświetlenia nazwisk klientów:

<HTML>

<HEAD>

<TITLE>

Użycie rekordów hierarchicznych w XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Użycie rekordów hierarchicznych w XML

</H1>

<XML SRC="dostawy.xml" ID=dsoKlient></XML>

<TABLE DATASRC="#dsoKlient" BORDER="1">

<TR>

<TH><DIV DATAFLD="NAZWISKO"></DIV></TH>

<TD>

.

.

.

Następnie wiążemy tabelę z polem REKORD bieżącego rekordu:

<HTML>

<HEAD>

<TITLE>

Użycie rekordów hierarchicznych w XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Użycie rekordów hierarchicznych w XML

</H1>

<XML SRC="dostawy.xml" ID=dsoKlient></XML>

<TABLE DATASRC="#dsoKlient" BORDER="1">

<TR>

<TH><DIV DATAFLD="NAZWISKO"></DIV></TH>

<TD>

<TABLE DATASRC="#dsoKlient" DATAFLD="REKORD">

.

.

.

Aby w każdym rekordzie DOSTAWA wyświetlić pola DATA i SUMA, wiążemy wewnętrzną tabelę ze zbiorem danych REKORD.DOSTAWA:

<HTML>

<HEAD>

<TITLE>

Użycie rekordów hierarchicznych w XML

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Użycie rekordów hierarchicznych w XML

</H1>

<XML SRC="dostawy.xml" ID=dsoKlient></XML>

<TABLE DATASRC="#dsoKlient" BORDER="1">

<TR>

<TH><DIV DATAFLD="NAZWISKO"></DIV></TH>

<TD>

<TABLE DATASRC="#dsoKlient" DATAFLD="REKORD">

<TR>

<TD>

<TABLE DATASRC="#dsoKlient"

CELLPADDING="5"

DATAFLD="REKORD.DOSTAWA">

<TR ALIGN="LEFT">

<TH>Data</TH>

<TH>Wartość</TH>

</TR>

<TR ALIGN="LEFT">

<TD><DIV DATAFLD="DATA"></DIV></TD>

<TD><DIV DATAFLD="SUMA"></DIV></TD>

</TR>

</TABLE>

</TD>

</TR>

</TABLE>

</TD>

</TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

W Internet Explorerze dane pokażą się w takiej postaci, jak na rysunku 6.7. Obok każdego nazwiska podano daty i koszty poszczególnych dostaw - mamy hierarchiczne zestawy danych pochodzących z XML.

Rysunek 6.7.

Wyświetlanie hierarchicznych zbiorów rekordów w Internet Explorerze

0x01 graphic

Obsługa danych hierarchicznych o zmiennej długości

Pokazano już, jak DSO Internet Explorera obsługują hierarchiczne zbiory rekordów. Używane przez nas podzbiory zawierały po dwa rekordy, ale taki przykład odbiega nieco od rzeczywistości. Zwykle podzbiory mogą mieć bardzo różną długość. Jak ma w takiej sytuacji zachować się DSO? Przyjrzyj się następnemu dokumentowi, różnie.xml, w którym wewnętrzne zbiory mają od jednego do trzech rekordów DOSTAWA:

<?xml version="1.0" encoding="iso-8859-2"?>

<KLIENCI>

<KLIENT>

<NAZWISKO>Charles</NAZWISKO>

<REKORD>

<ID_KLIENTA>58704</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Szynka</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>7.90 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>5.80 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>5.80 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Franklin</NAZWISKO>

<REKORD>

<ID_KLIENTA>58705</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Warzywa</DZIAŁ>

<PRODUKT>Pomidory</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>12.00 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Phoebe</NAZWISKO>

<REKORD>

<ID_KLIENTA>58706</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Indyk</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>22.00 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>34.00 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Mark</NAZWISKO>

<REKORD>

<ID_KLIENTA>58707</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Wołowina</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>15.80 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>27.90 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

<KLIENT>

<NAZWISKO>Nancy</NAZWISKO>

<REKORD>

<ID_KLIENTA>58708</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mrożonki</DZIAŁ>

<PRODUKT>Brokuły</PRODUKT>

<DOSTAWA>

<DATA>2001.10.20</DATA>

<SUMA>7.90 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2001.10.25</DATA>

<SUMA>11.80 zł</SUMA>

</DOSTAWA>

<DOSTAWA>

<DATA>2002.03.05</DATA>

<SUMA>28800.00 zł</SUMA>

</DOSTAWA>

</REKORD>

</KLIENT>

</KLIENCI>

Tak naprawdę nie ma z tym problemu - oto strona, która pozwoli nam wyświetlić dane:

<HTML>

<HEAD>

<TITLE>

Zbiory hierarchiczne zmiennej wielkości

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Zbiory hierarchiczne zmiennej wielkości

</H1>

<XML SRC="różnie.xml" ID=dsoKlient></XML>

<TABLE DATASRC="#dsoKlient" BORDER="1">

<TR>

<TH><DIV DATAFLD="NAZWISKO"></DIV></TH>

<TD>

<TABLE DATASRC="#dsoKlient" DATAFLD="REKORD">

<TR>

<TD>

<TABLE DATASRC="#dsoKlient"

CELLPADDING="3"

DATAFLD="REKORD.DOSTAWA">

<TR ALIGN="LEFT">

<TH>Data</TH>

<TH>Wartość</TH>

</TR>

<TR ALIGN="LEFT">

<TD><DIV DATAFLD="DATA"></DIV></TD>

<TD><DIV DATAFLD="SUMA"></DIV></TD>

</TR>

</TABLE>

</TD>

</TR>

</TABLE>

</TD>

</TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

Wyniki pokazano na rysunku 6.8 - każdy zbiór rekordów DOSTAWA wyświetlany jest prawidłowo mimo różnej ich wielkości.

Rysunek 6.8.

Hierarchiczne zbiory rekordów w Internet Explorerze

0x01 graphic

Ten sam wynik można by uzyskać stosując zamiast wysp danych XML aplet DSO XML:

<HTML>

<HEAD>

<TITLE>

Zbiory hierarchiczne zmiennej wielkości

</TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>

Zbiory hierarchiczne zmiennej wielkości

</H1>

<APPLET CODE="com.ms.xml.dso.XMLDSO.class"

ID="klienci”

WIDTH="0" HEIGHT="0"

MAYSCRIPT="true">

<PARAM NAME="URL" VALUE="różnie.xml">

</APPLET>

<TABLE DATASRC="#klienci” BORDER="1">

<TR>

<TH><DIV DATAFLD="NAZWISKO"></DIV></TH>

<TD>

<TABLE DATASRC="#klienci” DATAFLD="REKORD">

<TR ALIGN="CENTER">

<TD>Sprzedaż</TD>

</TR>

<TR>

.

.

.

</TR>

</TABLE>

</TD>

</TR>

</TABLE>

</CENTER>

</BODY>

</HTML>

Przeszukiwanie danych XML

Stosując zbiory rekordów można zrobić wiele ciekawych rzeczy, czym zresztą w tym rozdziale się zajmowaliśmy. Na koniec jeszcze przyjrzymy się możliwością wyszukiwania specyficznych danych w bazie danych. Będziemy wyszukiwać klienta, którego nazwisko pasować będzie do podanych przez użytkownika warunków wyboru.

Zmodyfikujemy nasz plik klient.xml - dodamy drugiego klienta o nazwisku Nancy, aby upewnić się, że zawsze „wyłapujemy” wszystkie przypadki wystąpienia poszukiwanej danej. Nowy plik będzie nazywał się wiele.xml:

<?xml version="1.0" encoding="iso-8859-2"?>

<KLIENCI>

<KLIENT>

<NAZWISKO>Charles</NAZWISKO>

<ID_KLIENTA>58704</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Szynka</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Franklin</NAZWISKO>

<ID_KLIENTA>58705</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Warzywa</DZIAŁ>

<PRODUKT>Pomidory</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Phoebe</NAZWISKO>

<ID_KLIENTA>58706</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Indyk</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Mark</NAZWISKO>

<ID_KLIENTA>58707</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mięso</DZIAŁ>

<PRODUKT>Wołowina</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Nancy</NAZWISKO>

<ID_KLIENTA>58708</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Mrożonki</DZIAŁ>

<PRODUKT>Brokuły</PRODUKT>

</KLIENT>

<KLIENT>

<NAZWISKO>Nancy</NAZWISKO>

<ID_KLIENTA>58709</ID_KLIENTA>

<DATA_ZAKUPU>2001.10.15</DATA_ZAKUPU>

<DZIAŁ>Warzywa</DZIAŁ>

<PRODUKT>Pomidory</PRODUKT>

</KLIENT>

</KLIENCI>

Po przygotowaniu wyspy danych i powiązaniu jej z plikiem wiele.xml utworzymy nową funkcję znajdzPasujace, która wyszukiwać będzie nazwisko klienta, który interesuje użytkownika. Wprawdzie zbiory rekordów ADOR mają metodę find służącą do przeszukiwania baz danych, ale warunki wyszukiwania podaje się tej metodzie w postaci wyrażenia SQL (język SQL jest typowym językiem do obsługi baz danych), natomiast Internet Explorer takich wyrażeń nie potrafi obsłużyć. Wobec tego utworzymy pętlę języka JavaScript, w której będziemy wyszukiwać pasujące nazwiska klientów.

Użytkownik może podać nazwisko, które chce znaleźć, w polu tekstowym - nazwiemy je text1. Kiedy użytkownik kliknie przycisk, wywołana zostanie funkcja znajdzPasujace. Podane przez użytkownika nazwisko zamienimy na małe litery (użyjemy metody toLowerCase obiektu String), aby wynik wyszukiwania nie zależał od sposobu zapisania danych, wynik konwersji zapiszemy w zmiennej szukajTego:

<HTML>

<HEAD>

<TITLE>

Wyszukiwanie danych w bazach XML

</TITLE>

<XML ID="klienci” SRC="wiele.xml"></XML>

<SCRIPT LANGUAGE="JavaScript">

function znajdzPasujace()

{

var szukajTego = form1.text1.value.toLowerCase()

.

.

.

Teraz zrobimy pętlę działającą na wszystkich rekordach ze zbioru, wartość pola NAZWISKO z każdego rekordu zapisywać będziemy w zmiennej obecnaNazwa, przy czym nazwisko to zamieniać będziemy na małe litery:

<HTML>

<HEAD>

<TITLE>

Wyszukiwanie danych w bazach XML

</TITLE>

<XML ID="klienci” SRC="wiele.xml"></XML>

<SCRIPT LANGUAGE="JavaScript">

function znajdzPasujace()

{

var szukajTego = form1.text1.value.toLowerCase()

while (!klienci.recordset.EOF) {

var obecnaNazwa = new String(klienci.recordset("NAZWISKO"))

obecnaNazwa = obecnaNazwa.toLowerCase()

.

.

.

klienci.recordset.moveNext()

}

}

</SCRIPT>

</HEAD>

.

.

.

Aby sprawdzić, czy bieżące nazwisko pasuje do nazwiska poszukiwanego przez użytkownika, użyjemy metody indexOf obiektu String. Metoda ta zwróci wartość 0 lub większą, jeśli napis da się dopasować:

<HTML>

<HEAD>

<TITLE>

Wyszukiwanie danych w bazach XML

</TITLE>

<XML ID="klienci” SRC="wiele.xml"></XML>

<SCRIPT LANGUAGE="JavaScript">

function znajdzPasujace()

{

var szukajTego = form1.text1.value.toLowerCase()

while (!klienci.recordset.EOF) {

var obecnaNazwa = new String(klienci.recordset("NAZWISKO"))

obecnaNazwa = obecnaNazwa.toLowerCase()

if (obecnaNazwa.indexOf(szukajTego) >= 0) {

.

.

.

}

klienci.recordset.moveNext()

}

}

</SCRIPT>

</HEAD>

.

.

.

Teraz pozostaje już tylko wyświetlić pasujące rekordy przy pomocy elementu <DIV>, jak to robiliśmy dotąd. Trzeba też dodać przycisk i pole tekstowe, aby użytkownik mógł z naszym kodem się porozumieć:

<HTML>

<HEAD>

<TITLE>

Wyszukiwanie danych w bazach XML

</TITLE>

<XML ID="klienci” SRC="wiele.xml"></XML>

<SCRIPT LANGUAGE="JavaScript">

function znajdzPasujace()

{

var szukajTego = form1.text1.value.toLowerCase()

while (!klienci.recordset.EOF) {

var obecnaNazwa = new String(klienci.recordset("NAZWISKO"))

obecnaNazwa = obecnaNazwa.toLowerCase()

if (obecnaNazwa.indexOf(szukajTego) >= 0) {

komunikatDiv.innerHTML +=

klienci.recordset("NAZWISKO") + " (ID " +

klienci.recordset("ID_KLIENTA") + ") kupił(a) " +

klienci.recordset("PRODUKT") + " z działu " +

klienci.recordset("DZIAŁ") + " dnia " +

klienci.recordset("DATA_ZAKUPU") + ".<BR>"

}

klienci.recordset.moveNext()

}

}

</SCRIPT>

</HEAD>

<BODY>

<CENTER>

<H1>

Wyszukiwanie danych w bazach XML

</H1>

<FORM ID="form1">

Szukane nazwisko: <INPUT TYPE="TEXT" NAME="text1">

<BR>

<BR>

<INPUT TYPE="BUTTON" VALUE="Wyszukaj"

ONCLICK="znajdzPasujace()">

</FORM>

</CENTER>

<DIV ID="komunikatDiv"></DIV>

</BODY>

</HTML>

Wyniki pokazano na rysunku 6.9 - odnalezione zostały oba rekordy, które znalezione być powinny.

Rysunek 6.9.

Wyszukiwanie danych w bazach danych XML

0x01 graphic

W tym przykładzie użyliśmy wysp danych, ale oczywiście równie dobrze do załadowania danych z pliku wiele.xml można byłoby użyć apletu DSO XML. Tym razem pokażemy jeszcze jedną cechę tego apletu: jak dotąd podawaliśmy zerową wysokość i zerową szerokość, ale przez to aplet ten nie wyświetla wyników swojego działania, a wystarczyłoby przyznać mu nieco miejsca na stronie:

<HTML>

<HEAD>

<TITLE>

Wyszukiwanie danych w bazach XML

</TITLE>

<SCRIPT LANGUAGE="JavaScript">

function znajdzPasujace()

{

var szukajTego = form1.text1.value.toLowerCase()

while (!klienci.recordset.EOF) {

var obecnaNazwa = new String(klienci.recordset("NAZWISKO"))

obecnaNazwa = obecnaNazwa.toLowerCase()

if (obecnaNazwa.indexOf(szukajTego) >= 0) {

komunikatDiv.innerHTML +=

klienci.recordset("NAZWISKO") + " (ID " +

klienci.recordset("ID_KLIENTA") + ") kupił(a) " +

klienci.recordset("PRODUKT") + " z działu " +

klienci.recordset("DZIAL") + " dnia " +

klienci.recordset("DATA_ZAKUPU") + ".<BR>"

}

klienci.recordset.moveNext()

}

}

</SCRIPT>

</HEAD>

<BODY>

<CENTER>

<H1>

Wyszukiwanie danych w bazach XML

</H1>

<APPLET CODE="com.ms.xml.dso.XMLDSO.class"

ID="klienci”

WIDTH="400" HEIGHT="50"

MAYSCRIPT="true">

<PARAM NAME="URL" VALUE="wiele.xml">

</APPLET>

<FORM ID="form1">

Szukane nazwisko: <INPUT TYPE="TEXT" NAME="text1">

<BR>

<BR>

<INPUT TYPE="BUTTON" VALUE="Wyszukaj"

ONCLICK="znajdzPasujace()">

</FORM>

</CENTER>

<DIV ID="komunikatDiv"></DIV>

</BODY>

</HTML>

Wyniki pokazano na rysunku 6.10. Obiekt DSO XML wyświetlił komunikat o prawidłowym załadowaniu pliku XML (Successfully loaded XML from...), tło apletu jest zielone, gdyż nie wystąpił żaden błąd - gdyby jakiś się pojawił, pojawiłby się w aplecie jego komunikat.

Rysunek 6.10.

Wyszukiwanie danych w bazach XML przy użyciu DSO XML

0x01 graphic

I w ten oto sposób zakończyliśmy omawianie wiązania danych w Internet Explorerze.

Niestety, pojawiają się w tym przypadku kłopoty z polskimi literami, co widać na rysunku. Niepoprawnie wyświetlone są polskie litery w tabeli z danymi, choć są już poprawne w statycznym kodzie HTML. Co gorsza, nie są obsługiwane znaczniki zawierające polskie litery, w naszym przypadku element DZIAŁ. Dlatego w kodzie stosujemy element DZIAL, taka sama zmiana była oczywiście konieczna także w źródle danych, czyli w dokumencie klient.xml. (przyp. tłum.)

Pamiętać trzeba o braku obsługi polskich liter w przypadku Javy na Windows 98 - konieczna była korekta pliku XML (zmiana DZIAŁ na DZIAL) (przyp. tłum.)

Jeśli nie zmienisz znaczników <DZIAŁ> na <DZIAL>, to mimo poprawnego kodowania polskich liter zgodnie z normą ISO 8859-2 tło apletu będzie czerwone i komunikat poinformuje nas o wystąpieniu nieprawidłowego znaku. (przyp. tłum.)

32 Część I Podstawy obsługi systemu WhizBang (Nagłówek strony)

Rozdział 1 Pierwsze kroki (Nagłówek strony)

32 C:\Moje dokumenty\Wojtek Romowicz\Książki\XML Vademecum profesjonalisty\r06-01.doc

C:\Moje dokumenty\Wojtek Romowicz\Książki\XML Vademecum profesjonalisty\r06-01.doc 1



Wyszukiwarka

Podobne podstrony:
r03-01, ## Documents ##, XML Vademecum profesjonalisty
r05-01, ## Documents ##, XML Vademecum profesjonalisty
r04-01, ## Documents ##, XML Vademecum profesjonalisty
r07-01, ## Documents ##, XML Vademecum profesjonalisty
r12-01, ## Documents ##, XML Vademecum profesjonalisty
r08-01, ## Documents ##, XML Vademecum profesjonalisty
r11-01, ## Documents ##, XML Vademecum profesjonalisty
r09-01, ## Documents ##, XML Vademecum profesjonalisty
r10-01, ## Documents ##, XML Vademecum profesjonalisty
Projektowanie Baz Danych Xml Vademecum Profesjonalisty [XML]
Projektowanie baz danych XML Vademecum profesjonalisty pxmlvp 2
Projektowanie baz danych XML Vademecum profesjonalisty pxmlvp
Projektowanie baz danych XML Vademecum profesjonalisty 2
Projektowanie Baz Danych Xml Vademecum Profesjonalisty [XML]
Projektowanie baz danych XML Vademecum profesjonalisty pxmlvp
Projektowanie Baz Danych Xml Vademecum Profesjonalisty R 5 Architektura Systemu Baz Danych
Projektowanie baz danych XML Vademecum profesjonalisty
Asembler dla procesorow Intel Vademecum profesjonalisty asinvp
CorelDRAW 11 Vademecum profesjonalisty Tom 2

więcej podobnych podstron