|
|
XML Type Library használata
XML 8. rész
|
|
Példaprogram letöltése
43862 bájt
|
Korábban szó volt róla, hogy egy XML dokumentumban komplett adatbázisok is tárolhatók. Most annak járunk utána, hogy egy ilyen dokumentumból miként nyerhetők ki a benne tárolt adatok.
A feladat a következő:
Adott egy XML dokumentum, amiben több cég megbízásait tároljuk. Minden céghez több megbízás tartozhat, és minden megbízáshoz egy-egy személy. A dokumentum megnyitásakor a cégek nevét beolvassuk egy listába, ahol ABC sorrendbe rendezzük. Ha kiválasztunk egy céget a listából, akkor mellette megjelennek a cég, a céghez tartozó megbízások, valamint a megbízott személyek adatai.
A feladat megoldásához szükség lesz az MS XML Type Library-ra is.
Első lépésben tehát megnyitjuk a dokumentumot, és elkészítjük a cégek listáját. Ezt érdemes mindjárt a Form OnCreate eseményénél elvégezni.
A dokumentum kezeléséhez szükség lesz egy IXMLDOMDocument típusú objektumra, amit a CoDOMDocument.Create függvénnyel hozhatunk létre. Ezután a load függvénnyel megnyitjuk az XML dokumentumot. Ha ez valamilyen okból kifolyólag sikertelen (pl. hibás a DTD), akkor a függvény visszatérési értéke hamis, ellenkező esetben pedig igaz.
procedure TForm1.FormCreate(Sender: TObject);
…
XMLDoc:=CoDOMDocument.Create;
if not XMLDoc.load(ExtractFilePath(Application.ExeName)+'customer.xml') then begin
ShowMessage('Fájl betöltése sikertelen!');
Application.Terminate;
end;
Egy ciklusban végigmegyünk az első szinten lévő csomópontokon, amiket az XMLDoc objektum childNodes property-jén keresztül érünk el. Az adott szinten lévő csomópontok számát a childNodes.length property-ből tudhatjuk meg. Az éppen vizsgált csomópontot a DOMNode objektumban tároljuk el, aminek a típusa IXMLDOMNode. A csomópont nevét a nodeName property-ből olvashatjuk ki. Megvizsgáljuk, hogy ez "customers"-e. Ha az, akkor elérkeztünk ahhoz az elemhez, ami az összes többi elemet magában foglalja. Ekkor egy újabb ciklust indítunk, amiben már ennek az elemnek a csomópontjait fogjuk megvizsgálni. Ezeket szintén a chilNodes property-n keresztül érjük el. Ha megvizsgáljuk a customer.dtd fájlt, akkor láthatjuk, hogy a customers elem csak customer elemeket tartalmazhat, ezért itt nem kell külön megvizsgálnunk az elem nevét. Van viszont egy másik feladat, méghozzá az elem azonosítójának és a cég nevének eltárolás a listában. Az azonosítóhoz szükség lesz egy újabb objektumra, ez lesz a CustNoNode. Ebben eltároljuk az aktuális csomópont (ami mint tudjuk, egy customer elem) attribútumához tartozó objektumot. Ezt a childNodes.attributes.getNamedItem függvénnyel érhetjük el. Ennek a függvénynek egy paramétere van, a lekérdezett attribútum neve. Ha megvan az attribútum, akkor ennek text property-jéből kiolvashatjuk az értékét is. Ennek első karakterére nem lesz szükségünk, mert az mindig "C", viszont az utána álló számra annál inkább, amit el is tárolunk a CustID változóban. A cég nevét a company elem tartalmazza, ami minden esetben a customer elem első eleme. Mivel tudjuk a DTD-ből, hogy ez mindig létezik, ezért nem kell név szerint keresni, elég, ha a firstChild property-vel hivatkozunk rá. Ennek text property-jéből kiolvashatjuk a cég nevét, amit a CustNo változóval együtt a ListBox.Items.AddObject függvénnyel hozzáadunk a listához.
for i:=0 to XMLDoc.childNodes.length-1 do begin
DOMNode:=XMLDoc.childNodes[i];
if DOMNode.nodeName='customers' then begin
for t:=0 to DOMNode.childNodes.length-1 do begin
CustNoNode:=DOMNode.childNodes[t].attributes.getNamedItem('azon');
CustID:=StrToInt(Copy(CustNoNode.text, 2, length(CustNoNode.text)-1));
ListBox1.Items.AddObject(DOMNode.childNodes[t].firstChild.text, TObject(CustID));
end;
end;
end;
end;
A céglista tehát már megvan, a következő feladat a listából kiválasztott cég adatainak megjelenítése. Ezt a műveletet legcélszerűbb a ListBox1 OnClick eseményénél elvégezni.
A cégek egyedi azonosítóit a ListBox1.Items.Objects property-ben tároltuk el. Ennek elejére egy "C" karaktert illesztünk, és az eredményt eltároljuk az id változóban. Ez a karaktersorozat az XML dokumentumon belül egyértelműen azonosít egy customer elemet. A nodeFromID függvénnyel megkereshetjük azt a csomópontot (esetünkben elemet), amely a paraméterként átadott egyedi azonosítóval rendelkezik. A függvény visszatérési értéke egy IXMLDOMNode objektum ha van ilyen csomópont, vagy nil, ha nincs.
procedure TForm1.ListBox1Click(Sender: TObject);
…
id:='C'+IntToStr(integer(ListBox1.Items.Objects[ListBox1.ItemIndex]));
node:=XMLDoc.nodeFromID(id);
if Assigned(node) then begin
Memo1.Lines.Append(ID);
Az orders IXMLDOMNodeList típusú objektumban eltároljuk a megtalált elem (customer) gyermek elemeinek listáját.
orders:=node.childNodes;
for i:=0 to orders.length-1 do begin
node:=orders.item[i];
Ha az elem neve order, akkor az order objektumban eltároljuk az elem "azon" attribútumának értékét. Ezt az attributes.getNamedItem függvénnyel kérdezhetjük le. Minden order elem tartalmaz egy darab employee elemet, amit egyszerűen megkaphatunk a firstChild property-ből. Ezután employee elemek gyermek elemeinek tartalmát kigyűjtjük a már ismert módszerrel.
if node.nodeName='order' then begin
order:=node.attributes.getNamedItem('azon');
Memo1.Lines.Append('');
Memo1.Lines.Append('Order No: '+order.text);
employee:=node.firstChild;
Memo1.Lines.Append(' '+employee.nodeName+':');
for e:=0 to employee.childNodes.length-1 do begin
Memo1.Lines.Append(' '+employee.childNodes[e].nodeName+': '+employee.childNodes[e]
.text);
end;
Ha a customer elem éppen vizsgált gyermek eleme nem order, akkor egyszerűen megjelenítjük az elem nevét és tartalmát.
end else begin
Memo1.Lines.Append(node.nodeName+': '+node.text);
end;
…
|
Könyv
Ez a cikk megtalálható ebben a könyvben:
Delphi Software Offline 2001 évkönyv 454. oldal
Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!
|