Za mnoge Delphi programere, spremanje postavki je povezano s korištenjem INI datoteke u svojim programima. Primenu ove metode, u manje ili više ozbiljnim projektima, treba izbegavati, jer ograničava fleksibilnost, što onemogućava dalje širenje programa. Treba reći da je ovaj pristup prilično popularan zbog svoje jednostavnosti korištenja i prisutnosti ugrađenih alata u razvojnom okruženju.
Međutim, strukturirano XML datoteke. Njihova prednost je što broj parametara možda nije fiksiran. Da biste ovo bolje razumjeli, razmotrite konkretan primjer.
U programu USSearch, kada kliknete na unos, pojavljuje se kontekstni meni u kojem se prikazuje lista stavki. Ove stavke su komande, koje se zauzvrat učitavaju iz datoteke postavki. U slučaju da su postavke pohranjene u INI fajl, onda bi program mogao da sačuva i učita određeni broj komandi, na primer 10 ili 50. Čim bude potrebna veća vrednost, moraćete ponovo da napišete kod i da ga ponovo kompajlirate u skladu sa tim.
Primjena pristupa koristeći XML datoteke, moći ćemo dinamički učitavati sve parametre odjeljka. Osim toga, konfiguracijski fajl će postati elegantniji, bez suvišnog numeriranja parametara. ali, standardnim sredstvima raditi sa XML Delphi ima mnogo nedostataka, pa preporučujem korištenje standardna biblioteka MSXML... Obično je uključen po defaultu u operativni sistemi Windows porodica.
Za povezivanje MSXML, moramo generirati datoteku interfejsa sa listom svih funkcija uvozom sa COM servera. Napisano je mnogo detaljnih članaka o tome kako uvesti interfejs, ali predlažem da preuzmete datoteku MSXML2_TLB.PAS spreman za upotrebu. Nakon što se datoteka preuzme, stavite je pored svog projekta ili je ispustite u fasciklu lib okruženja Delphi. Tako će svi kreirani programi moći koristiti modul MSXML, samo trebate dodati liniju MSXML2_TLB u upotrebu.
Radi jasnoće, razmotrite sljedeći primjer korištenja ove biblioteke:
Procedure LoadData; var XMLDoc: DOMDocument; Root: IXMLDOMElement; započeti XMLDoc: = CoDOMDocument.Create; XMLDoc.Load ("settins.xml"); Root: = XMLDoc.DocumentElement; ShowMessage (Root.SelectSingleNode ("veličina / širina"). Tekst); Korijen: = nula; XMLDoc: = nil; kraj;
Prvo se kreira instanca klase DOMDocument, a zatim se sadržaj datoteke settings.xml učitava u memoriju. Pošto, prema standardu, bilo koji XML datoteka mora sadržavati root oznaku (in u ovom slučaju config), onda ga moramo dobiti pomoću funkcije DocumentElement... Zatim se sadržaj prikazuje između oznaka.
Ovdje se primjenjuje metoda SelectSingleNode, koja uzima string kao parametar
Uprkos činjenici da se tema rada sa XML-om u Delphiju naširoko raspravlja na Internetu, pitanja o ovoj temi često se pojavljuju na svim vrstama foruma.
Napisao sam i ovo, ali bih se želio vratiti na stvarni slučaj brzog raščlanjivanja XML datoteke i izdvajanja podataka, što sam radio danas na poslu. Nije mi trebalo više od 5 minuta da dobijem potrebne podatke.
Pozadina. Danas sam trebao obraditi podatke o instalirane programe na kompjuterima korisnika (da, da, identifikujemo pirate :)). Tehničko odeljenje mi je dalo ove informacije izvučene od nesuđenih korisnika preko mreže koja koristi WMI. Program koji su koristili generiše izvještaje XML format... U skladu s tim, donijeli su mi brdo XML datoteka prilično složene strukture, iz kojih sam samo trebao izvući naziv instaliranih softverskih proizvoda. Tretman . Nakon što sam ručno pogledao nekoliko fajlova, shvatio sam da neće trebati dugo da ostarim i odlučio sam da napišem mali konverter. Nakon što sam pokrenuo Delphi, odabrao sam XML DataBinding objekat iz spremišta i dodao mu jedan od fajlova. Ostavio sam sve postavke i parametre prema zadanim postavkama i kao rezultat toga, modul sa veliki iznos klase i sučelja za pristup elementima ove XML datoteke. Nisam se dugo bavio strukturom časova, odmah sam prešao na pisanje konvertera. U novoj aplikaciji za konzolu, napisao sam prilično jednostavan kod:
program XML2TXT;
koristi
obrasci,
klase, SysUtils,
SoftwareXML u "SoftwareXML.pas";
procedura CovertXML2Text;
var
softbase: IXMLSTDSoftwareType;
i: cijeli broj;
sr: TSearchRec;
CurDir: string;
ExportFile: TStringList;
početi
CurDir: = IncludeTrailingPathDelimiter (ExtractFilePath (Application.ExeName));
ako je FindFirst (CurDir + "*. xml", faAnyFile, sr) = 0 onda
ponovi
ExportFile: = TStringList.Create;
softbase: = LoadSTDSoftware (Pchar (CurDir + sr.Name));
za i: = 0 do softbase.InstalledSoftware.source.software.Count - 1 do
ExportFile.Add (softbase.InstalledSoftware.source.software [i] .DisplayName);
ExportFile.Sort;
ExportFile.SaveToFile (CurDir + softbase.InstalledSoftware.Source.servername + ". Txt");
ExportFile.Free;
dok FindNext (sr) 0;
kraj;
početi
Application.Initialize;
CovertXML2Text;
kraj.
Kao rezultat, dobio sam po jedan uređivač teksta za svaki računar u mreži, koji sadrži listu instaliranog softvera.
Smatram da će ovaj kod zahtijevati neko objašnjenje. Na primjer, zašto sam koristio modul Forms u aplikaciji na konzoli i pozvao proceduru Application.Initialize;?
Zapravo je jednostavno - ovo je mali hak koji vam omogućava da koristite XML Data Binding u aplikaciji za konzolu. Zato što je tvrdoglavo odbijao da inicijalizira klasu za rad sa XML-om. Još nisam shvatio prave razloge - danas je vrijeme bilo važno, već sam proveo 4 od 5 minuta boreći se sa ovom greškom. :) Mislim da se kasnije pozabavim ovim problemom i napišem šta je pravi razlog.
Čudna softbase klasa je kreirana iz XML datoteke - to je ime osnovnog elementa, a softbase.InstalledSoftware.source.software [i] .DisplayName je samo navigacija kroz ugniježđene elemente do željenog i dobijanje njegove vrijednosti.
Ovako jedan od najvecih brze načine rad sa XML-om u Delphiju.
XML se sve više koristi za pohranjivanje informacija i njihovu razmjenu između aplikacija i web stranica. Mnoge aplikacije koriste ovaj jezik kao osnovni jezik za pohranjivanje podataka, dok ga druge koriste za izvoz i uvoz XML podataka. Dakle, vrijeme je da programeri počnu razmišljati o tome kako se XML podaci mogu koristiti u njihovim vlastitim aplikacijama.
U ovom članku ćemo pogledati XML Document Object Model (DOM) i Microsoftovu implementaciju XML DOM-a.
XML DOM je objektni model koji pruža programeru objekte za učitavanje i obradu XML datoteka. Objektni model se sastoji od sljedećih osnovnih objekata: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap i XMLDOMParseError. Svaki od ovih objekata (osim XMLDOMParseError) sadrži svojstva i metode koje vam omogućavaju da dobijete informacije o objektu, manipulirate vrijednostima i strukturom objekta i navigirate strukturom XML dokumenta.
Pogledajmo glavne XML DOM objekte i pokažimo neke primjere njihove upotrebe u Borland Delphi.
Korištenje XML DOM-a u Borland Delphiju
Da biste koristili Microsoft XML DOM u Delphi aplikacijama, potrebno je da povežete odgovarajuću biblioteku tipova na projekat. Da bismo to učinili, izvršavamo naredbu Project | Import Type Library i u dijalogu Import Type Library izaberite biblioteku Microsoft XML verzije 2.0 (verzija 2.0), koja se obično nalazi u datoteci Windows \ System \ MSXML.DLL
Nakon klika na dugme Create Unit kreiraće se modul interfejsa MSXML_TLB koji će nam omogućiti korišćenje XML DOM objekata: DOMDocument, XMLDocument, XMLHTTPRequest i niz drugih, implementiranih u biblioteci MSXML.DLL. Referenca na MSXML_TLB modul mora biti na listi Koristi.
XML DOM uređaj
Model objekta dokumenta predstavlja XML dokument u strukturi stabla grana. XML DOM API-ji omogućavaju aplikacijama da se kreću kroz stablo dokumenta i manipulišu njegovim granama. Svaka grana može imati određeni tip (DOMNodeType), prema kojem se određuju nadređena i podređena grana. Većina XML dokumenata sadrži grane elementa tipa, atributa i teksta. Atributi su posebna vrsta grane i nisu podređene grane. Za upravljanje atributima koristite posebne metode obezbjeđuju XML DOM objekti.
Pored implementacije interfejsa koji preporučuje World Wide Web Consortium (W3C), Microsoft XML DOM sadrži metode koje podržavaju XSL, XSL obrasce, prostore imena i tipove podataka. Na primjer, metoda SelectNodes vam omogućava da koristite sintaksu XSL uzorka za pronalaženje grana u određenom kontekstu, a metoda TransformNode podržava korištenje XSL-a za izvođenje transformacija.
Testirajte XML dokument
Kao primjer XML dokumenta, uzmimo muzički CD-ROM direktorij, koji ima sljedeću strukturu:
Sada smo spremni da počnemo gledati XML DOM objektni model, počevši od objekta XMLDOMDocument.
XML dokument - XMLDOMDocument objekat
Rad sa XML dokumentom počinje njegovim učitavanjem. Da bismo to učinili, koristimo metodu Load, koja ima samo jedan parametar koji specificira URL učitanog dokumenta. Prilikom učitavanja datoteka s lokalnog diska navodi se samo puno ime datoteke (protokol datoteke: /// u ovom slučaju može biti izostavljen). Ako je XML dokument pohranjen kao string, koristite metodu LoadXML za učitavanje dokumenta.
Svojstvo Async se koristi za kontrolu načina na koji se dokument učitava (sinhrono ili asinkrono). Po defaultu, ovo svojstvo je postavljeno na True, što ukazuje da se dokument učitava asinhrono i kontrola se vraća aplikaciji prije nego što se dokument u potpunosti učita. U suprotnom, dokument se učitava sinhrono, a zatim morate provjeriti vrijednost svojstva ReadyState da biste saznali da li se dokument učitao ili ne. Također možete kreirati rukovatelj za događaj OnReadyStateChange koji će preuzeti kontrolu kada se promijeni vrijednost svojstva ReadyState.
Sljedeće pokazuje kako učitati XML dokument pomoću metode Load:
Koristi ... MSXML_TLB ... proceduru TForm1.Button1Click (Pošiljalac: TObject); var XMLDoc: IXMLDOMDocument; započeti XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // // Ovdje je kod koji manipulira // XML dokumentom i njegovim granama // XMLDoc: = Nil; kraj;
Nakon što se dokument učita, možemo pristupiti njegovim svojstvima. Dakle, svojstvo NodeName će sadržavati vrijednost #document, svojstvo NodeTypeString će sadržavati vrijednost dokumenta, a svojstvo URL će sadržavati datoteku: /// C: /DATA/DATA.xml vrijednost.
Obrada grešaka
Od posebnog interesa su svojstva vezana za obradu dokumenata pri učitavanju. Na primjer, svojstvo ParseError vraća XMLDOMParseError objekt koji sadrži informacije o grešci koja se dogodila tijekom obrade dokumenta.
Da biste napisali rukovalac greškama, možete dodati sljedeći kod:
Var XMLError: IXMLDOMParseError; ... XMLDoc.Load (‘C: \ DATA \ DATA.xml’); XMLError: = XMLDoc.ParseError; Ako XMLError.ErrorCode<>0 Tada // // Ovdje obrađujemo grešku // Else Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: = Ništa;
Da biste saznali koje informacije se vraćaju u slučaju greške, promijenite sljedeći unos direktorija:
uklanjanje elementa za zatvaranje
Sada napišimo kod koji vraća vrijednosti svojstva objekta XMLDOMParseError:
XMLError: = XMLDoc.ParseError; Ako XMLError.ErrorCode<>0 Zatim sa XMLError-om, Memo1.Lines počinje Add ('File:' + URL); Dodaj ('Kôd:' + IntToStr (ErrorCode)); Dodaj ('Greška:' + Razlog); Dodaj ('Tekst:' + SrcText); Dodaj („Linija:“ + IntToStr (Linija)); Dodaj ('Pozicija:' + IntToStr (LinePos)); kraj Else Memo1.Lines.Add (XMLDoc.XML); End;
i izvršite našu aplikaciju. Kao rezultat, dobijamo sljedeće informacije o grešci.
Kao što možete vidjeti iz gornjeg primjera, informacije koje vraća XMLDOMParseError objekat su sasvim dovoljne da lokaliziraju grešku i razumiju uzrok njenog nastanka.
Sada ćemo vratiti element za zatvaranje
Pristup stablu dokumenta
Da biste pristupili stablu dokumenta, možete ili dobiti korijenski element, a zatim iterirati njegove podređene grane ili pronaći određenu granu. U prvom slučaju, osnovni element dobijamo kroz svojstvo DocumentElement, koje vraća objekat tipa XMLDOMNode. Evo kako koristiti svojstvo DocumentElement da dobijete sadržaj svakog podređenog elementa:
Var čvor: IXMLDOMNode; Root: IXMLDOMElement; I: Integer; ... Root: = XMLDoc.DocumentElement; Za I: = 0 do Root.ChildNodes.Length-1 do Početni čvor: = Root.ChildNodes.Item [I]; Memo1.Lines.Add (Čvor.Tekst); End;
Za naš XML dokument dobijamo sledeći tekst.
Ako nas zanima određena grana ili grana ispod prve podređene grane, možemo koristiti metodu NodeFromID ili metodu GetElementByTagName objekta XMLDOMDocument.
Metoda NodeFromID zahtijeva jedinstveni identifikator kako je definirano u XML šemi ili definiciji tipa dokumenta (DTD) i vraća granu s tim identifikatorom.
Metoda GetElementByTagName zahtijeva string sa određenim elementom (oznakom) i vraća sve grane sa ovim elementom. Evo kako koristiti ovu metodu da pronađete sve izvođače u našem CD-ROM imeniku:
Čvorovi: IXMLDOMNodeList; Čvor: IXMLDOMNode; ... Čvorovi: = XMLDoc.GetElementsByTagName (‘UMJETNIK’); Za I: = 0 do Nodes.Length-1 do Početni čvor: = Nodes.Item [I]; Memo1.Lines.Add (Čvor.Tekst); End;
Za naš XML dokument dobit ćemo sljedeći tekst
Imajte na umu da SelectNodes metoda objekta XMLDOMNode pruža fleksibilniji način pristupa granama dokumenta. Ali više o tome u nastavku.
Grana dokumenta - XMLDOMNode objekat
Objekt XMLDOMNode predstavlja granu dokumenta. Već smo se susreli sa ovim objektom kada smo dobili osnovni element dokumenta:
Root: = XMLDoc.DocumentElement;
Da biste dobili informacije o grani XML dokumenta, možete koristiti svojstva objekta XMLDOMNode (Tablica 1).
Za pristup podacima pohranjenim u grani, uobičajeno je koristiti ili svojstvo NodeValue (dostupno za atribute, tekstualne grane, komentare, upute za obradu i CDATA odjeljke) ili svojstvo Text, koje vraća tekstualni sadržaj grane, ili svojstvo NodeTypedValue. Potonje se, međutim, može koristiti samo za grane sa upisanim stavkama.
Kretanje po stablu dokumenta
XMLDOMNode objekat pruža mnogo načina za kretanje kroz stablo dokumenta. Na primjer, da biste pristupili roditeljskoj grani, koristite svojstvo ParentNode (tip XMLDOMNode), pristupite podređenim granama kroz svojstva ChildNodes (tip XMLDOMNodeList), FirstChild i LastChild (tip XMLDOMNode), itd. Svojstvo OwnerDocument vraća XMLDOMDocument objekt koji identificira sam XML dokument. Gore navedena svojstva olakšavaju navigaciju stablom dokumenta.
Sada prođimo kroz sve grane XML dokumenta:
Root: = XMLDoc.DocumentElement; Za I: = 0 do Root.ChildNodes.Length-1 do Početni čvor: = Root.ChildNodes.Item [I]; Ako Node.HasChildNodes onda GetChilds (Čvor, 0); End;
Kao što je gore navedeno, SelectNodes objekta XMLDOMNode pruža fleksibilniji način pristupa granama dokumenta. Osim toga, postoji metoda SelectSingleNode koja vraća samo prvu granu dokumenta. Obje ove metode vam omogućavaju da definirate XSL šablone za pretraživanje grana.
Pogledajmo proces korištenja SelectNodes metode za dohvaćanje svih grana koje imaju CD granu i PRICE podgranu:
Root: = XMLDoc.DocumentElement; Čvorovi: = Root.SelectNodes (‘CD / PRICE’);
Sve PRICE podgrane grane CD-a će biti smještene u kolekciju Čvorova. Vratit ćemo se na raspravu o XSL predlošcima malo kasnije.
Manipulisanje podređenim granama
Za manipulaciju podređenim granama možemo koristiti metode objekta XMLDOMNode (Tablica 2).
Da biste potpuno izbrisali zapis o prvom disku, potrebno je pokrenuti sljedeći kod:
Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Čvor: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // Dobivamo korijenski element Root: = XMLDoc.DocumentElement; Čvor: = Root; // Uklonimo prvu podređenu granu Node.RemoveChild (Node.FirstChild);
Imajte na umu da u ovom primjeru brišemo prvu podređenu granu. Kako ukloniti prvi element prve podređene grane je prikazano u nastavku:
Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Čvor: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // Dobivamo korijenski element Root: = XMLDoc.DocumentElement; // i prva podređena grana Čvor: = Root.FirstChild; // Uklonimo prvu podređenu granu Node.RemoveChild (Node.FirstChild);
U gornjem primjeru, izbrisali smo ne prvu granu
Sada dodajmo novu granu. Ispod je kod koji pokazuje kako dodati novi muzički CD-ROM unos:
Var NewNode: IXMLDOMNode; Dijete: IXMLDOMNode; ... // Kreiraj novu granu -
Gornji kod pokazuje sljedeći niz koraka za dodavanje nove grane:
- Kreiranje nove grane pomoću metode CreateNode:
- kreiranje elementa pomoću metode CreateNode;
- dodavanje elementa u granu pomoću metode AppendChild;
- postavljanje vrijednosti elementa kroz svojstvo Text;
- … Ponovite za sve elemente.
- Dodavanje nove grane u dokument pomoću metode AppendChild.
Podsjetimo da metoda AppendChild dodaje granu na kraj stabla. Da biste dodali granu na određeno mjesto u stablu, morate koristiti metodu InsertBefore.
Skup grana - XMLDOMNodeList objekt
Objekt XMLNodeList sadrži listu grana, koja se može izgraditi pomoću metoda SelectNodes ili GetElementsByTagName, a također se može dobiti iz svojstva ChildNodes.
Već smo raspravljali o upotrebi ovog objekta u primjeru koji je dat u odjeljku "Kretanje po stablu dokumenta". Ovdje ćemo dati neke teorijske komentare.
Broj grana na listi može se dobiti kao vrijednost svojstva Length. Grane su indeksirane od 0 do Length-1, a svaka pojedinačna grana je dostupna preko odgovarajuće indeksirane stavke u polju Item.
Kretanje kroz listu grana može se obaviti i korištenjem metode NextNode, koja vraća sljedeću granu na listi, ili Nil ako je trenutna grana posljednja. Da biste se vratili na vrh liste, pozovite metodu Reset.
Kreirajte i sačuvajte dokumente
Dakle, pokrili smo kako možete dodati grane i elemente postojećim XML dokumentima. Sada kreirajmo XML dokument u hodu. Prije svega, zapamtite da se dokument može učitati ne samo iz URL-a, već i iz običnog niza. Evo kako kreirati korijenski element, koji se zatim može koristiti za dinamičku izgradnju ostalih elemenata (što smo već pokrili u odjeljku Manipuliranje podređenim granama):
Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Čvor: IXMLDOMNode; S: WideString; ... S: = ‘
Nakon što napravite XML dokument, sačuvajte ga u datoteku koristeći metodu Save. Na primjer:
XMLDoc.Save ('C: \ DATA \ NEWCD.XML');
Osim spremanja u datoteku, metoda Save vam omogućava da spremite XML dokument u novi XMLDOMDocument objekt. U ovom slučaju, dokument je u potpunosti obrađen i, kao rezultat, provjerava se njegova struktura i sintaksa. Evo kako da sačuvate dokument na drugom objektu:
Procedura TForm1.Button2Click (Pošiljalac: TObject); var XMLDoc2: IXMLDOMDocument; započeti XMLDoc2: = CoDOMDocument.Create; XMLDoc.Save (XMLDoc2); Memo2.Lines.Add (XMLDoc2.XML); ... XMLDoc2: = Ništa; kraj;
Zaključno, metoda Save vam također omogućava da spremite XML dokument u druge COM objekte koji podržavaju IStream, IPersistStream ili IPersistStreamInit sučelja.
Korištenje XSL predložaka
Kada smo raspravljali o metodi SelectNodes objekta XMLDOMNode, spomenuli smo da ona pruža fleksibilniji način pristupa granama dokumenta. Fleksibilnost je u tome što možete specificirati XSL predložak kao kriterij za odabir grana. Takvi predlošci pružaju moćan mehanizam za pronalaženje informacija u XML dokumentima. Na primjer, da biste dobili listu svih muzičkih CD-ROM naslova u našem direktoriju, možete pokrenuti sljedeći upit:
Da biste saznali koji diskovi izvođača izlaze u SAD-u, zahtjev se formira na sljedeći način:
Čvorovi: = Root.SelectNodes (‘CD / ARTIST’);
Evo kako pronaći prvi disk u direktoriju:
Čvorovi: = Root.SelectNodes (‘CD / TITLE’);
i zadnje:
Čvorovi: = Root.SelectNodes (‘CD / TITLE’);
Da biste pronašli diskove Boba Dylana, možete pokrenuti sljedeći upit:
Čvorovi: = Root.SelectNodes (‘CD [$ bilo koji $ ARTIST =” Bob Dylan ”] / TITLE’);
i da bismo dobili listu diskova napravljenih nakon 1985. godine, pokrećemo sljedeći upit:
Čvorovi: = Root.SelectNodes (‘CD / TITLE’);
Detaljnija rasprava o XSL sintaksi zahtijeva posebnu publikaciju. Kako bih zaintrigirao čitatelje i podstakao daljnja istraživanja, navest ću samo jedan mali primjer moguće upotrebe XSL-a. Recimo da treba da konvertujemo naš katalog u običnu HTML tabelu. Koristeći tradicionalne metode, moramo iterirati preko svih grana stabla i za svaki primljeni element formirati odgovarajuće oznake
Koristeći XSL, jednostavno kreiramo predložak (ili stylesheet) koji određuje šta i kako transformirati. Zatim prekrivamo ovaj predložak na naš katalog - i gotovi ste: imamo tekst XSL šablona koji transformiše katalog u tabelu (listing 2).
Kod za prekrivanje XSL predloška u našem direktoriju izgleda ovako:
Procedura TForm1.Button2Click (Pošiljalac: TObject); var XSLDoc: IXMLDOMDocument; započeti XSLDoc: = CoDOMDocument.Create; XSLDoc.Load (‘C: \ DATA \ DATA.xsl’); Memo2.Text: = XMLDoc.TransformNode (XSLDoc); XSLDoc: = Ništa; kraj;
Zaključujući našu raspravu o XSL-u, treba reći da se ovaj jezik trenutno aktivno koristi za transformaciju između različitih XML dokumenata, kao i za formatiranje dokumenata.
Zaključak
Iz očiglednih razloga, nemoguće je pokriti sve Microsoft XML DOM objekte i dati primjere njihove upotrebe u jednom članku. Ovdje smo se upravo dotakli osnovnih pitanja korištenja XML DOM-a u aplikacijama. Table 3 prikazuje sve objekte implementirane u Microsoft XML DOM.
ComputerPres 12 "2000
XML se sve više koristi za pohranjivanje informacija i njihovu razmjenu između aplikacija i web stranica. Mnoge aplikacije koriste ovaj jezik kao osnovni jezik za pohranjivanje podataka, dok ga druge koriste za izvoz i uvoz XML podataka. Dakle, vrijeme je da programeri počnu razmišljati o tome kako se XML podaci mogu koristiti u njihovim vlastitim aplikacijama.
U ovom članku ćemo pogledati XML Document Object Model (DOM) i Microsoftovu implementaciju XML DOM-a.
XML DOM je objektni model koji pruža programeru objekte za učitavanje i obradu XML datoteka. Objektni model se sastoji od sljedećih osnovnih objekata: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap i XMLDOMParseError. Svaki od ovih objekata (osim XMLDOMParseError) sadrži svojstva i metode koje vam omogućavaju da dobijete informacije o objektu, manipulirate vrijednostima i strukturom objekta i navigirate strukturom XML dokumenta.
Pogledajmo glavne XML DOM objekte i pokažimo neke primjere njihove upotrebe u Borland Delphi.
Korištenje XML DOM-a u Borland Delphiju
Da biste koristili Microsoft XML DOM u Delphi aplikacijama, potrebno je da povežete odgovarajuću biblioteku tipova na projekat. Da bismo to učinili, izvršavamo naredbu Project | Import Type Library i u dijalogu Import Type Library izaberite biblioteku Microsoft XML verzije 2.0 (verzija 2.0), koja se obično nalazi u datoteci Windows \ System \ MSXML.DLL
Nakon klika na dugme Create Unit kreiraće se modul interfejsa MSXML_TLB koji će nam omogućiti korišćenje XML DOM objekata: DOMDocument, XMLDocument, XMLHTTPRequest i niz drugih, implementiranih u biblioteci MSXML.DLL. Referenca na MSXML_TLB modul mora biti na listi Koristi.
XML DOM uređaj
Model objekta dokumenta predstavlja XML dokument u strukturi stabla grana. XML DOM API-ji omogućavaju aplikacijama da se kreću kroz stablo dokumenta i manipulišu njegovim granama. Svaka grana može imati određeni tip (DOMNodeType), prema kojem se određuju nadređena i podređena grana. Većina XML dokumenata sadrži grane elementa tipa, atributa i teksta. Atributi su posebna vrsta grane i nisu podređene grane. Za manipulisanje atributima koriste se posebne metode koje pružaju XML DOM objekti.
Pored implementacije interfejsa koji preporučuje World Wide Web Consortium (W3C), Microsoft XML DOM sadrži metode koje podržavaju XSL, XSL obrasce, prostore imena i tipove podataka. Na primjer, metoda SelectNodes vam omogućava da koristite sintaksu XSL uzorka za pronalaženje grana u određenom kontekstu, a metoda TransformNode podržava korištenje XSL-a za izvođenje transformacija.
Testirajte XML dokument
Kao primjer XML dokumenta, uzmimo muzički CD-ROM direktorij, koji ima sljedeću strukturu:
Sada smo spremni da počnemo gledati XML DOM objektni model, počevši od objekta XMLDOMDocument.
XML dokument - XMLDOMDocument objekat
Rad sa XML dokumentom počinje njegovim učitavanjem. Da bismo to učinili, koristimo metodu Load, koja ima samo jedan parametar koji specificira URL učitanog dokumenta. Prilikom učitavanja datoteka s lokalnog diska navodi se samo puno ime datoteke (protokol datoteke: /// u ovom slučaju može biti izostavljen). Ako je XML dokument pohranjen kao string, koristite metodu LoadXML za učitavanje dokumenta.
Svojstvo Async se koristi za kontrolu načina na koji se dokument učitava (sinhrono ili asinkrono). Po defaultu, ovo svojstvo je postavljeno na True, što ukazuje da se dokument učitava asinhrono i kontrola se vraća aplikaciji prije nego što se dokument u potpunosti učita. U suprotnom, dokument se učitava sinhrono, a zatim morate provjeriti vrijednost svojstva ReadyState da biste saznali da li se dokument učitao ili ne. Također možete kreirati rukovatelj za događaj OnReadyStateChange koji će preuzeti kontrolu kada se promijeni vrijednost svojstva ReadyState.
Sljedeće pokazuje kako učitati XML dokument pomoću metode Load:
Koristi ... MSXML_TLB ... proceduru TForm1.Button1Click (Pošiljalac: TObject); var XMLDoc: IXMLDOMDocument; započeti XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // // Ovdje je kod koji manipulira // XML dokumentom i njegovim granama // XMLDoc: = Nil; kraj;
Nakon što se dokument učita, možemo pristupiti njegovim svojstvima. Dakle, svojstvo NodeName će sadržavati vrijednost #document, svojstvo NodeTypeString će sadržavati vrijednost dokumenta, a svojstvo URL će sadržavati datoteku: /// C: /DATA/DATA.xml vrijednost.
Obrada grešaka
Od posebnog interesa su svojstva vezana za obradu dokumenata pri učitavanju. Na primjer, svojstvo ParseError vraća XMLDOMParseError objekt koji sadrži informacije o grešci koja se dogodila tijekom obrade dokumenta.
Da biste napisali rukovalac greškama, možete dodati sljedeći kod:
Var XMLError: IXMLDOMParseError; ... XMLDoc.Load (‘C: \ DATA \ DATA.xml’); XMLError: = XMLDoc.ParseError; Ako XMLError.ErrorCode<>0 Tada // // Ovdje obrađujemo grešku // Else Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: = Ništa;
Da biste saznali koje informacije se vraćaju u slučaju greške, promijenite sljedeći unos direktorija:
uklanjanje elementa za zatvaranje
Sada napišimo kod koji vraća vrijednosti svojstva objekta XMLDOMParseError:
XMLError: = XMLDoc.ParseError; Ako XMLError.ErrorCode<>0 Zatim sa XMLError-om, Memo1.Lines počinje Add ('File:' + URL); Dodaj ('Kôd:' + IntToStr (ErrorCode)); Dodaj ('Greška:' + Razlog); Dodaj ('Tekst:' + SrcText); Dodaj („Linija:“ + IntToStr (Linija)); Dodaj ('Pozicija:' + IntToStr (LinePos)); kraj Else Memo1.Lines.Add (XMLDoc.XML); End;
i izvršite našu aplikaciju. Kao rezultat, dobijamo sljedeće informacije o grešci.
Kao što možete vidjeti iz gornjeg primjera, informacije koje vraća XMLDOMParseError objekat su sasvim dovoljne da lokaliziraju grešku i razumiju uzrok njenog nastanka.
Sada ćemo vratiti element za zatvaranje
Pristup stablu dokumenta
Da biste pristupili stablu dokumenta, možete ili dobiti korijenski element, a zatim iterirati njegove podređene grane ili pronaći određenu granu. U prvom slučaju, osnovni element dobijamo kroz svojstvo DocumentElement, koje vraća objekat tipa XMLDOMNode. Evo kako koristiti svojstvo DocumentElement da dobijete sadržaj svakog podređenog elementa:
Var čvor: IXMLDOMNode; Root: IXMLDOMElement; I: Integer; ... Root: = XMLDoc.DocumentElement; Za I: = 0 do Root.ChildNodes.Length-1 do Početni čvor: = Root.ChildNodes.Item [I]; Memo1.Lines.Add (Čvor.Tekst); End;
Za naš XML dokument dobijamo sledeći tekst.
Ako nas zanima određena grana ili grana ispod prve podređene grane, možemo koristiti metodu NodeFromID ili metodu GetElementByTagName objekta XMLDOMDocument.
Metoda NodeFromID zahtijeva jedinstveni identifikator kako je definirano u XML šemi ili definiciji tipa dokumenta (DTD) i vraća granu s tim identifikatorom.
Metoda GetElementByTagName zahtijeva string sa određenim elementom (oznakom) i vraća sve grane sa ovim elementom. Evo kako koristiti ovu metodu da pronađete sve izvođače u našem CD-ROM imeniku:
Čvorovi: IXMLDOMNodeList; Čvor: IXMLDOMNode; ... Čvorovi: = XMLDoc.GetElementsByTagName (‘UMJETNIK’); Za I: = 0 do Nodes.Length-1 do Početni čvor: = Nodes.Item [I]; Memo1.Lines.Add (Čvor.Tekst); End;
Za naš XML dokument dobit ćemo sljedeći tekst
Imajte na umu da SelectNodes metoda objekta XMLDOMNode pruža fleksibilniji način pristupa granama dokumenta. Ali više o tome u nastavku.
Grana dokumenta - XMLDOMNode objekat
Objekt XMLDOMNode predstavlja granu dokumenta. Već smo se susreli sa ovim objektom kada smo dobili osnovni element dokumenta:
Root: = XMLDoc.DocumentElement;
Da biste dobili informacije o grani XML dokumenta, možete koristiti svojstva objekta XMLDOMNode (Tablica 1).
Za pristup podacima pohranjenim u grani, uobičajeno je koristiti ili svojstvo NodeValue (dostupno za atribute, tekstualne grane, komentare, upute za obradu i CDATA odjeljke) ili svojstvo Text, koje vraća tekstualni sadržaj grane, ili svojstvo NodeTypedValue. Potonje se, međutim, može koristiti samo za grane sa upisanim stavkama.
Kretanje po stablu dokumenta
XMLDOMNode objekat pruža mnogo načina za kretanje kroz stablo dokumenta. Na primjer, da biste pristupili roditeljskoj grani, koristite svojstvo ParentNode (tip XMLDOMNode), pristupite podređenim granama kroz svojstva ChildNodes (tip XMLDOMNodeList), FirstChild i LastChild (tip XMLDOMNode), itd. Svojstvo OwnerDocument vraća XMLDOMDocument objekt koji identificira sam XML dokument. Gore navedena svojstva olakšavaju navigaciju stablom dokumenta.
Sada prođimo kroz sve grane XML dokumenta:
Root: = XMLDoc.DocumentElement; Za I: = 0 do Root.ChildNodes.Length-1 do Početni čvor: = Root.ChildNodes.Item [I]; Ako Node.HasChildNodes onda GetChilds (Čvor, 0); End;
Kao što je gore navedeno, SelectNodes objekta XMLDOMNode pruža fleksibilniji način pristupa granama dokumenta. Osim toga, postoji metoda SelectSingleNode koja vraća samo prvu granu dokumenta. Obje ove metode vam omogućavaju da definirate XSL šablone za pretraživanje grana.
Pogledajmo proces korištenja SelectNodes metode za dohvaćanje svih grana koje imaju CD granu i PRICE podgranu:
Root: = XMLDoc.DocumentElement; Čvorovi: = Root.SelectNodes (‘CD / PRICE’);
Sve PRICE podgrane grane CD-a će biti smještene u kolekciju Čvorova. Vratit ćemo se na raspravu o XSL predlošcima malo kasnije.
Manipulisanje podređenim granama
Za manipulaciju podređenim granama možemo koristiti metode objekta XMLDOMNode (Tablica 2).
Da biste potpuno izbrisali zapis o prvom disku, potrebno je pokrenuti sljedeći kod:
Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Čvor: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // Dobivamo korijenski element Root: = XMLDoc.DocumentElement; Čvor: = Root; // Uklonimo prvu podređenu granu Node.RemoveChild (Node.FirstChild);
Imajte na umu da u ovom primjeru brišemo prvu podređenu granu. Kako ukloniti prvi element prve podređene grane je prikazano u nastavku:
Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Čvor: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // Dobivamo korijenski element Root: = XMLDoc.DocumentElement; // i prva podređena grana Čvor: = Root.FirstChild; // Uklonimo prvu podređenu granu Node.RemoveChild (Node.FirstChild);
U gornjem primjeru, izbrisali smo ne prvu granu
Sada dodajmo novu granu. Ispod je kod koji pokazuje kako dodati novi muzički CD-ROM unos:
Var NewNode: IXMLDOMNode; Dijete: IXMLDOMNode; ... // Kreiraj novu granu -
Gornji kod pokazuje sljedeći niz koraka za dodavanje nove grane:
- Kreiranje nove grane pomoću metode CreateNode:
- kreiranje elementa pomoću metode CreateNode;
- dodavanje elementa u granu pomoću metode AppendChild;
- postavljanje vrijednosti elementa kroz svojstvo Text;
- … Ponovite za sve elemente.
- Dodavanje nove grane u dokument pomoću metode AppendChild.
Podsjetimo da metoda AppendChild dodaje granu na kraj stabla. Da biste dodali granu na određeno mjesto u stablu, morate koristiti metodu InsertBefore.
Skup grana - XMLDOMNodeList objekt
Objekt XMLNodeList sadrži listu grana, koja se može izgraditi pomoću metoda SelectNodes ili GetElementsByTagName, a također se može dobiti iz svojstva ChildNodes.
Već smo raspravljali o upotrebi ovog objekta u primjeru koji je dat u odjeljku "Kretanje po stablu dokumenta". Ovdje ćemo dati neke teorijske komentare.
Broj grana na listi može se dobiti kao vrijednost svojstva Length. Grane su indeksirane od 0 do Length-1, a svaka pojedinačna grana je dostupna preko odgovarajuće indeksirane stavke u polju Item.
Kretanje kroz listu grana može se obaviti i korištenjem metode NextNode, koja vraća sljedeću granu na listi, ili Nil ako je trenutna grana posljednja. Da biste se vratili na vrh liste, pozovite metodu Reset.
Kreirajte i sačuvajte dokumente
Dakle, pokrili smo kako možete dodati grane i elemente postojećim XML dokumentima. Sada kreirajmo XML dokument u hodu. Prije svega, zapamtite da se dokument može učitati ne samo iz URL-a, već i iz običnog niza. Evo kako kreirati korijenski element, koji se zatim može koristiti za dinamičku izgradnju ostalih elemenata (što smo već pokrili u odjeljku Manipuliranje podređenim granama):
Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Čvor: IXMLDOMNode; S: WideString; ... S: = ‘
Nakon što napravite XML dokument, sačuvajte ga u datoteku koristeći metodu Save. Na primjer:
XMLDoc.Save ('C: \ DATA \ NEWCD.XML');
Osim spremanja u datoteku, metoda Save vam omogućava da spremite XML dokument u novi XMLDOMDocument objekt. U ovom slučaju, dokument je u potpunosti obrađen i, kao rezultat, provjerava se njegova struktura i sintaksa. Evo kako da sačuvate dokument na drugom objektu:
Procedura TForm1.Button2Click (Pošiljalac: TObject); var XMLDoc2: IXMLDOMDocument; započeti XMLDoc2: = CoDOMDocument.Create; XMLDoc.Save (XMLDoc2); Memo2.Lines.Add (XMLDoc2.XML); ... XMLDoc2: = Ništa; kraj;
Zaključno, metoda Save vam također omogućava da spremite XML dokument u druge COM objekte koji podržavaju IStream, IPersistStream ili IPersistStreamInit sučelja.
Korištenje XSL predložaka
Kada smo raspravljali o metodi SelectNodes objekta XMLDOMNode, spomenuli smo da ona pruža fleksibilniji način pristupa granama dokumenta. Fleksibilnost je u tome što možete specificirati XSL predložak kao kriterij za odabir grana. Takvi predlošci pružaju moćan mehanizam za pronalaženje informacija u XML dokumentima. Na primjer, da biste dobili listu svih muzičkih CD-ROM naslova u našem direktoriju, možete pokrenuti sljedeći upit:
Da biste saznali koji diskovi izvođača izlaze u SAD-u, zahtjev se formira na sljedeći način:
Čvorovi: = Root.SelectNodes (‘CD / ARTIST’);
Evo kako pronaći prvi disk u direktoriju:
Čvorovi: = Root.SelectNodes (‘CD / TITLE’);
i zadnje:
Čvorovi: = Root.SelectNodes (‘CD / TITLE’);
Da biste pronašli diskove Boba Dylana, možete pokrenuti sljedeći upit:
Čvorovi: = Root.SelectNodes (‘CD [$ bilo koji $ ARTIST =” Bob Dylan ”] / TITLE’);
i da bismo dobili listu diskova napravljenih nakon 1985. godine, pokrećemo sljedeći upit:
Čvorovi: = Root.SelectNodes (‘CD / TITLE’);
Detaljnija rasprava o XSL sintaksi zahtijeva posebnu publikaciju. Kako bih zaintrigirao čitatelje i podstakao daljnja istraživanja, navest ću samo jedan mali primjer moguće upotrebe XSL-a. Recimo da treba da konvertujemo naš katalog u običnu HTML tabelu. Koristeći tradicionalne metode, moramo iterirati preko svih grana stabla i za svaki primljeni element formirati odgovarajuće oznake
Koristeći XSL, jednostavno kreiramo predložak (ili stylesheet) koji određuje šta i kako transformirati. Zatim prekrivamo ovaj predložak na naš katalog - i gotovi ste: imamo tekst XSL šablona koji transformiše katalog u tabelu (listing 2).
Kod za prekrivanje XSL predloška u našem direktoriju izgleda ovako:
Procedura TForm1.Button2Click (Pošiljalac: TObject); var XSLDoc: IXMLDOMDocument; započeti XSLDoc: = CoDOMDocument.Create; XSLDoc.Load (‘C: \ DATA \ DATA.xsl’); Memo2.Text: = XMLDoc.TransformNode (XSLDoc); XSLDoc: = Ništa; kraj;
Zaključujući našu raspravu o XSL-u, treba reći da se ovaj jezik trenutno aktivno koristi za transformaciju između različitih XML dokumenata, kao i za formatiranje dokumenata.
Zaključak
Iz očiglednih razloga, nemoguće je pokriti sve Microsoft XML DOM objekte i dati primjere njihove upotrebe u jednom članku. Ovdje smo se upravo dotakli osnovnih pitanja korištenja XML DOM-a u aplikacijama. Table 3 prikazuje sve objekte implementirane u Microsoft XML DOM.
ComputerPres 12 "2000
Pozdravljam sve! Nekoliko godina sam pisao na Matlabu, a onda sam bio nestrpljiv da napišem program na Delphiju.
Moram da naučim kako da radim sa xml dokumentima. Radim u RAD Stiduo XE3. Postoji komponenta TXMLDocument, vjerovatno poznata mnogim Delphi programerima. Čini se da može mnogo. Ali problem je što ne postoji jasna dokumentacija i opis za to. Pomoć u RAD Studiju je sranje, jer tamo nema normalnih informacija; samo raštrkana po stranicama oskudna pomoć o nekim metodama i procedurama (bez primjera i normalnog opisa). Preturao po cijelom internetu. Pronađene su samo teme na forumima sa rešenjima određenih problema, gde morate još sat vremena da pogađate šta radi ova ili ona linija povezana sa pristupom xml datoteci.
Također mi je potreban priručnik o glavnim funkcijama, procedurama i metodama koje se koriste pri radu sa xml-om. Udžbenik, priručnik, opis. Ili barem "xml u Delphiju za lutke". Na primjer:
Da biste otvorili xml datoteku, koristite metodu XMLDocument1.LoadFromFile ("filemane.xml"), gdje je ime datoteke ime datoteke.
Varijabla lista čvorova tipa IXMLNode se koristi za pohranjivanje liste djece. Metoda Xmldocument1.DocumentElement (gdje je XMLDocument1 xml datoteka koju treba ispitati) koristi se za definiranje ove liste.
Za upit o sadržaju podređenog elementa "element1", koristite metodu XMLDocument1.DocumentElement.ChildNodes ["element1"]. Text ....
iu tom duhu dalje na sve primijenjene metode, procedure, tipove podataka.
Gdje mogu pronaći slične priručnike/opise? Ko može pomoći?
Ako vam treba konkretan zadatak, opisat ću ga.
Postoji xml dokument u obliku:
Neki tekst
Neki tekst greške
Drugi tekst greške
U programskom kodu imamo:
var
...
roditelj, dijete1: IXMLNode;
početi
XMLDocument1.LoadFromFile ("f: \ filename.x ml");
XMLDocument1.Active: = istina;
.
.
kraj
Šta treba da naučite da radite:
(Unaprijed se izvinjavam ako sam pogrešno imenovao komponente xml dokumenta)
1. Dobijte ime osnovnog elementa (u našem slučaju ltm), kao i listu njegovih atributa (verzija, tip) i njihove vrijednosti ("1.0", "postavke").
2. Dobijte broj elemenata koji su potomci korijena. U ovom slučaju ima ih 7: templateFiles, dimenzije, hotspot, hotspot, data, data, data. Dobiti nazive elemenata (tagova) (templateFiles, dimenzije, itd.). Nakon što dobijem broj elemenata i naučim kako da izdvojim njihova imena, napravit ću petlju od 0 do count-1 i učiniti ono što mi treba.
3. Dobijte broj i listu atributa potrebnog elementa. Na primjer, za element vruće tačke. Tačan odgovor bi bila 4 atributa. Za prvi hotspot element, to će biti ime, stil, scena, ath. Za drugi - isto, samo umjesto atributa ath - atribut rz.
Obratite pažnju da se u datoteci nalaze 2 hotspot elementa, sa različitim atributima. Evo kako raditi s njima (ako postoji više od 1 elementa istog imena)?
Želim ovako: Dobijem listu djece po rel. do osnovnog (vidi str. 2), pokrenite for petlju kroz njih i pronađite elemente hotspota u kojima je parametar name jednak traženom (recimo "hs015_2" - sigurno će biti jedan takav element). Da li je moguće nekako riješiti ovaj problem bez petlje? To jest, dobiti vrijednost atributa scene za element hotspota s imenom = "hs015_2"?
4. Uradite gore navedeno za čvorove i elemente koji su djeca u odnosu na djecu. U mom primjeru, čvor (dijete i roditelj i.
Ako sam dobro razumio, morate nekako prenijeti sadržaj čvora na varijabilna like IXMLNode i uradite isto kao u stavkama 1-3. pa?
5. Morate naučiti kako promijeniti gornje parametre (podesite svoje).
Čini se tako daleko. U ovoj fazi su mi najvažnije sintaktičke konstrukcije.
Tko je vlasnik ove teme, neka napiše druge sintaktičke konstrukcije za rješavanje gornjih problema (kako dobiti atribute, njihov broj, broj elemenata, njihova imena, itd.). Sada je glavna stvar savladati sintaksu, a svoj algoritam ću implementirati kasnije. Hvala puno unapred!
P.S. Zaista ne bih želio da pišem svoj XML parser od nule samo zato što ne postoji normalan opis za postojeće.