Mange Delphi-programmerere forbinder lagring av innstillinger med bruk INI filer i programmene dine. Søknad denne metoden, i mer eller mindre seriøse prosjekter, bør unngås, da det begrenser fleksibiliteten, noe som hindrer ytterligere utvidelse av programmet. Det er verdt å si at denne tilnærmingen er ganske populær på grunn av dens brukervennlighet og tilgjengeligheten av innebygde verktøy i utviklingsmiljøet.
Det ideelle alternativet for å lagre programinnstillinger er imidlertid strukturert XML filer. Deres fordel er at antall parametere kanskje ikke er faste. For bedre å forstå dette, la oss se på et spesifikt eksempel.
I USearch-programmet, når du klikker på en oppføring, vises en kontekstmeny som viser en liste over elementer. Disse elementene er kommandoer, som igjen lastes fra innstillingsfilen. Hvis innstillingene ble lagret i INI fil, så kan programmet lagre og laste et visst antall kommandoer, for eksempel 10 eller 50. Så snart en større verdi er nødvendig, må koden skrives om og kompileres deretter.
Å bruke tilnærmingen ved å bruke XML filer, vil vi kunne laste alle seksjonsparametere dynamisk. I tillegg til alt dette vil konfigurasjonsfilen bli mer elegant, uten overflødig nummerering av parametere. Imidlertid standard betyrå jobbe med XML Delphi har mange ulemper, så jeg anbefaler å bruke standardbiblioteket MSXML. Det er vanligvis inkludert som standard operativsystemer Windows-familien.
For å koble til MSXML, må vi generere en grensesnittfil med en liste over alle funksjoner ved å importere den fra COM-serveren. Det er skrevet ganske mye om hvordan man importerer et grensesnitt. detaljerte artikler, jeg foreslår at du laster ned filen MSXML2_TLB.PAS allerede klar til bruk. Etter at filen er lastet ned, plasser den ved siden av prosjektet ditt, eller slipp den inn i lib-mappen i Delphi-miljøet. Dermed vil alle opprettede programmer kunne bruke modulen MSXML, du trenger bare å legge til linjen MSXML2_TLB til bruk.
For klarhet, vurder følgende eksempel på bruk av dette biblioteket:
Prosedyre LoadData; var XMLDoc: DOMDocument;
Rot: IXMLDOMElement; begin XMLDoc:= CoDOMDocument.Create; XML XMLDoc.Load("settins.xml"); Root:= XMLDoc.DocumentElement; ShowMessage(Root.SelectSingleNode("størrelse/bredde").Tekst); Rot:= null; XMLDoc:= null; slutt;
. Deretter sendes innholdet mellom taggene ut
, som igjen er plassert mellom taggene
. Derfor, fra settings.xml-filen, vil metoden vår vise tekst i MessageBox "100px" 500 piksler
100 piksler SelectSingleNode-metoden brukes her, som tar en streng som en parameter Til tross for at emnet arbeid med XML i Delphi har blitt diskutert ganske mye på Internett, oppstår spørsmål om dette emnet ganske ofte på forskjellige fora. Jeg har også allerede skrevet om dette, men jeg vil gjerne komme tilbake til det virkelige tilfellet med en rask analyse XML-fil
og datautvinning jeg gjorde på jobben i dag. Det tok meg ikke mer enn 5 minutter å få de nødvendige dataene.
Bakgrunn. I dag trengte vi å behandle data om
installerte programmer
på brukernes datamaskiner (ja, ja, vi oppdager pirater :)). Den tekniske avdelingen ga meg denne informasjonen, fratatt intetanende brukere over nettverket ved hjelp av WMI. Programmet de brukte produserer rapporter i XML-format. Følgelig brakte de meg et berg av XML-filer med en ganske kompleks struktur som jeg bare trengte å trekke ut navnet på de installerte programvareproduktene fra.
Behandling. Etter å ha sett gjennom et par filer manuelt, innså jeg at det ikke ville vare lenge og bestemte meg for å skrive en liten omformer. Etter å ha lansert Delphi, valgte jeg XML DataBinding-objektet i depotet og matet det med en av filene. Jeg forlot alle innstillingene og parameterne som standard, og som et resultat opprettet jeg en modul med et stort antall klasser og grensesnitt for å få tilgang til elementene i denne XML-filen. Jeg brukte ikke mye tid på å finne ut klassestrukturen og gikk umiddelbart videre til å skrive en omformer.
I den nye konsollapplikasjonen skrev jeg ganske enkel kode:
program XML2TXT;
bruker
Skjemaer,
Klasser, SysUtils,
SoftwareXML i "SoftwareXML.pas";
prosedyre CovertXML2Text;
var
CurDir:= IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
hvis FindFirst(CurDir+"*.xml", faAnyFile, sr) = 0, så
gjenta
ExportFile:= TStringList.Create;
softbase:= LoadSTDSoftware(Pchar(CurDir+sr.Name));
for i:= 0 til 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;
til FindNext(sr) 0;
slutt;
var
Application.Initialize;
CovertXML2Tekst;
slutt.
Som et resultat opprettet jeg én tekstfil for hver datamaskin i nettverket, som inneholder en liste over installert programvare.
Jeg føler at denne koden krever litt forklaring. For eksempel, hvorfor brukte jeg Forms-modulen i en konsollapplikasjon og kalte Application.Initialize-prosedyren?
Det er faktisk enkelt – det er et lite hack som lar deg bruke XML Data Binding i en konsollapplikasjon. Fordi den hardnakket nektet å initialisere klassen for å jobbe med XML. Jeg har ikke funnet ut de virkelige årsakene ennå - tiden var viktig i dag, jeg brukte allerede 4 av 5 minutter på å kjempe mot denne feilen. :) Jeg tror jeg skal finne ut av dette problemet senere og skrive hva den egentlige årsaken er.
Den merkelige softbase-klassen ble opprettet på XML-basert fil - det var navnet på rotelementet, og softbase.InstalledSoftware.source.software[i].DisplayName - naviger ganske enkelt gjennom de nestede elementene til det ønskede og få verdien.
Det er faktisk slik en av de mest ser ut raske måter arbeider med XML i Delphi.
XML brukes i økende grad til å lagre informasjon og utveksle den mellom applikasjoner og nettsteder. Mange applikasjoner bruker dette språket som basisspråk for lagring av data, mens andre bruker det til eksport og import av XML-data. Dette betyr at det er på tide for utviklere å tenke på hvordan de kan bruke XML-data i sine egne applikasjoner.
I denne artikkelen vil vi se på XML Document Object Model (DOM) og dens implementering av Microsoft - Microsoft XML DOM.
XML DOM er en objektmodell som gir utvikleren objekter for å laste og behandle XML-filer. Objektmodellen består av følgende hovedobjekter: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap og XMLDOMParseError. Hvert av disse objektene (unntatt XMLDOMParseError) inneholder egenskaper og metoder som lar deg få informasjon om objektet, manipulere objektets verdier og struktur og navigere gjennom strukturen til XML-dokumentet.
La oss se på de viktigste XML DOM-objektene og gi noen eksempler på deres bruk i Borland Delphi.
Bruker XML DOM i Borland Delphi
For å bruke Microsoft XML DOM i Delphi-applikasjoner, må du koble riktig typebibliotek til prosjektet. For å gjøre dette, utfører vi kommandoen Project | Import Type Library og i dialogboksen Import Type Library velger du Microsoft XML versjon 2.0-biblioteket (versjon 2.0), som vanligvis ligger i filen Windows\System\MSXML.DLL
Etter å ha klikket på Create Unit-knappen, vil MSXML_TLB-grensesnittmodulen bli opprettet, som vil tillate oss å bruke XML DOM-objekter: DOMDocument, XMLDocument, XMLHTTPRequest og en rekke andre implementert i MSXML.DLL-biblioteket. En referanse til MSXML_TLB-modulen må være oppført i brukslisten.
XML DOM-enhet
Dokumentobjektmodellen representerer et XML-dokument som en trestruktur bestående av grener. XML DOM-programmeringsgrensesnitt lar applikasjoner navigere i dokumenttreet og manipulere grenene. Hver gren kan ha en spesifikk type (DOMNodeType), i henhold til hvilken overordnede og underordnede grener bestemmes.
I de fleste XML-dokumenter finner du grener som element, attributt og tekst. Attributter er en spesiell type gren og er ikke barnegrener. Attributter manipuleres ved hjelp av spesielle metoder levert av XML DOM-objekter.
I tillegg til å implementere World Wide Web Consortium (W3C) anbefalte grensesnitt, inneholder Microsoft XML DOM metoder som støtter XSL, XSL Patterns, Namespaces og datatyper. For eksempel lar SelectNodes-metoden deg bruke XSL Pattern Syntax for å finne grener innenfor en spesifikk kontekst, og TransformNode-metoden støtter bruken av XSL for å utføre transformasjoner.
Test XML-dokument
Nå er vi klare til å begynne å se på XML DOM-objektmodellen, som vi starter med XMLDOMDocument-objektet.
XML-dokument - XMLDOMDocument-objekt
Arbeid med et XML-dokument begynner med å laste det inn. For å gjøre dette bruker vi Load-metoden, som bare har én parameter som indikerer URL-en til dokumentet som skal lastes. Når du laster filer fra en lokal disk, spesifiseres kun hele filnavnet (fil:///-protokollen kan utelates i dette tilfellet). Hvis XML-dokumentet er lagret som en streng, bør du bruke LoadXML-metoden for å laste dokumentet.
For å kontrollere hvordan dokumentet lastes (synkront eller asynkront), bruk egenskapen Async. Som standard er denne egenskapen satt til True, noe som indikerer at dokumentet lastes asynkront og kontroll returneres til applikasjonen før dokumentet er fullstendig lastet. Ellers lastes dokumentet synkront, og da må du sjekke verdien til ReadyState-egenskapen for å finne ut om dokumentet er lastet inn eller ikke. Du kan også opprette en OnReadyStateChange-hendelsesbehandler som vil motta kontroll når verdien til ReadyState-egenskapen endres.
Følgende viser hvordan du laster et XML-dokument ved å bruke Load-metoden:
Bruker ... MSXML_TLB ... prosedyre TForm1.Button1Click(Sender: TObject);
var XMLDoc: IXMLDOMDocument;
begin XMLDoc:= CoDOMDocument.Create;
XMLDoc.Async:= False;
XMLDoc.Load('C:\DATA\DATA.xml');
// // Her er koden som manipulerer // XML-dokumentet og dets grener // XMLDoc:= Null;<>slutt;
Når dokumentet er lastet inn, kan vi få tilgang til egenskapene. Dermed vil NodeName-egenskapen inneholde verdien #document, NodeTypeString-egenskapen vil inneholde verdidokumentet, og URL-egenskapen vil inneholde verdien file:///C:/DATA/DATA.xml.
Feilhåndtering
La oss nå skrive kode som returnerer verdiene til egenskapene til XMLDOMParseError-objektet:
XMLError:= XMLDoc.ParseError;<>Hvis XMLError.ErrorCode
0 Med XMLError begynner Memo1.Lines Add('Fil: ' + URL);
Add('Kode: ' + IntToStr(Feilkode));
Add('Feil: ' + Årsak);
Add('Linje: ' + IntToStr(Linje));
Add(‘Posisjon: ‘ + IntToStr(LinePos));
end Else Memo1.Lines.Add(XMLDoc.XML);
Slutt;
og la oss kjøre applikasjonen vår. Som et resultat mottar vi følgende feilinformasjon.
Som du kan se fra eksempelet ovenfor, er informasjonen som returneres av XMLDOMParseError-objektet ganske nok til å lokalisere feilen og forstå årsaken til dens forekomst.
La oss nå gjenopprette det lukkende elementet
i vårt dokument og fortsette vår diskusjon om XML DOM.
Få tilgang til dokumenttreet
For å få tilgang til et dokumenttre kan du enten hente rotelementet og deretter iterere gjennom undergrenene, eller finne en bestemt gren. I det første tilfellet får vi rotelementet gjennom DocumentElement-egenskapen, som returnerer et objekt av typen XMLDOMNode. Følgende viser hvordan du bruker DocumentElement-egenskapen for å få innholdet til hvert underordnede element:
Var Node: IXMLDOMNode;
Et XMLDOMNode-objekt representerer en dokumentgren. Vi møtte allerede dette objektet da vi fikk rotelementet til dokumentet:
Root:= XMLDoc.DocumentElement;
For å få informasjon om grenen til et XML-dokument, kan du bruke egenskapene til XMLDOMNode-objektet (tabell 1).
For å få tilgang til data som er lagret i en gren, bruker du vanligvis enten NodeValue-egenskapen (tilgjengelig for attributter, tekstgrener, kommentarer, behandlingsinstruksjoner og CDATA-seksjoner), Text-egenskapen, som returnerer tekstinnholdet til grenen, eller NodeTypedValue-egenskapen . Sistnevnte kan imidlertid bare brukes for grener med maskinskrevne elementer.
Navigere i dokumenttreet
XMLDOMNode-objektet gir mange måter å navigere i dokumenttreet på. For å få tilgang til den overordnede grenen brukes for eksempel ParentNode-egenskapen (XMLDOMNode-type), underordnede grener får tilgang gjennom ChildNodes (XMLDOMNodeList-type), FirstChild og LastChild (XMLDOMNode-type), etc.
Egenskapen OwnerDocument returnerer et objekt av typen XMLDOMDocument som identifiserer selve XML-dokumentet. Egenskapene som er oppført ovenfor lar deg enkelt navigere i dokumenttreet.
La oss nå gå gjennom alle grenene til XML-dokumentet:
Root:= XMLDoc.DocumentElement;
For I:= 0 til Root.ChildNodes.Length-1 do Begin Node:= Root.ChildNodes.Item[I];
If Node.HasChildNodes Then GetChilds(Node,0);
Slutt;
Som nevnt ovenfor gir XMLDOMNode-objektets SelectNodes en mer fleksibel måte å få tilgang til dokumentgrener. I tillegg er det en SelectSingleNode-metode som bare returnerer den første grenen av dokumentet. Begge disse metodene lar deg spesifisere XSL-maler for å søke etter grener.
La oss gå gjennom prosessen med å bruke SelectNodes-metoden for å hente alle grener som har en CD-gren og en PRICE-undergren:
Root:= XMLDoc.DocumentElement; Nodes:= Root.SelectNodes('CD/PRIS');
Alle PRICE undergrener av CD-grenen vil bli plassert i Nodes-samlingen. Vi kommer tilbake til diskusjonen om XSL-maler litt senere.
Merk at i dette eksemplet sletter vi den første underordnede grenen.
Hvordan fjerne det første elementet i den første underordnede grenen er vist nedenfor:
Var XMLDoc: IXMLDOMDocument;
Node: IXMLDOMNode;
XMLDoc:= CoDOMDocument.Create;
La oss nå legge til en ny gren. Nedenfor er koden som viser hvordan du legger til en ny musikk-CD-ROM-oppføring:
- Var NewNode: IXMLDOMNode;
- Barn: IXMLDOMNode;
- ... // Opprett en ny gren -
- NewNode:= XMLDoc.CreateNode(1, 'CD', '');
- // Legg til et element
- Child:= XMLDoc.CreateNode(1,‘TITLE’,‘’);
// Legg til et element NewNode.AppendChild(Child);
// Og sett verdien Child.Text:= 'Pink Floyd';
XMLNodeList-objektet inneholder en liste over grener som kan bygges ved hjelp av SelectNodes- eller GetElementsByTagName-metodene, eller hentes fra ChildNodes-egenskapen.
Vi har allerede sett på bruken av dette objektet i eksemplet gitt i avsnittet "Navigere i dokumenttreet". Her presenterer vi noen teoretiske bemerkninger.
Antall grener i listen kan fås som verdien av Length-egenskapen. Grener har indekser fra 0 til Length-1, og hver enkelt gren er tilgjengelig gjennom elementet Element array med tilhørende indeks.
Navigering gjennom en liste over grener kan også gjøres ved å bruke NextNode-metoden, som returnerer neste gren i listen, eller Null hvis gjeldende gren er den siste.
For å gå tilbake til begynnelsen av listen, kall tilbakestillingsmetoden.
Opprette og lagre dokumenter
Så langt har vi sett på hvordan du kan legge til grener og elementer til eksisterende XML-dokumenter.
Var XMLDoc: IXMLDOMDocument;
Rot: IXMLDOMNode;
Node: IXMLDOMNode;
S: WideString;
... S:= '
';
Når vi diskuterte XMLDOMNode-objektets SelectNodes-metode, nevnte vi at det gir en mer fleksibel måte å få tilgang til dokumentgrener. Fleksibiliteten ligger i at du kan angi en XSL-mal som et kriterium for valg av grener. Slike maler gir en kraftig mekanisme for å søke informasjon i XML-dokumenter. For å få en liste over alle musikk-CD-ROM-titlene i katalogen vår kan du for eksempel kjøre følgende spørring:
For å finne ut hvilke artister som ble utgitt i USA, er forespørselen utformet som følger:
Nodes:= Root.SelectNodes('CD/ARTIST');
Følgende viser hvordan du finner den første stasjonen i katalogen:
Nodes:= Root.SelectNodes('CD/TITLE');
og den siste:
Nodes:= Root.SelectNodes('CD/TITLE');
For å finne Bob Dylan CD-er kan du kjøre følgende spørring:
Noder:= Root.SelectNodes(‘CD[$any$ ARTIST= ”Bob Dylan”]/TITLE’);
og for å få en liste over plater utgitt etter 1985, kjører vi følgende spørring:
Nodes:= Root.SelectNodes('CD/TITLE');
En mer detaljert diskusjon av XSL-syntaks krever et eget innlegg. For å fascinere leserne og oppmuntre til videre forskning, vil jeg gi bare ett lite eksempel på mulig bruk av XSL. La oss si at vi må konvertere katalogen vår til en vanlig HTML-tabell. Ved å bruke tradisjonelle metoder må vi gå gjennom alle grenene på treet og danne de riktige taggene for hvert element som mottas
Ved å bruke XSL lager vi ganske enkelt en mal (eller stilark) der vi angir hva som må konverteres og hvordan. Så overlegger vi denne malen på katalogen vår - og vi er ferdige: vi har teksten til en XSL-mal som konverterer katalogen til en tabell (oppføring 2).
Koden for å overlegge XSL-malen i katalogen vår ser slik ut:
Prosedyre TForm1.Button2Click(Sender: TObject);
var XSLDoc: IXMLDOMDocument;
begin XSLDoc:= CoDOMDocument.Create;
XSLDoc.Load('C:\DATA\DATA.xsl');
Memo2.Text:= XMLDoc.TransformNode(XSLDoc);
, som igjen er plassert mellom taggene
Jeg har også allerede skrevet, men jeg vil gjerne gå tilbake til det virkelige tilfellet med å raskt analysere en XML-fil og trekke ut data, som jeg gjorde i dag på jobben. Det tok meg ikke mer enn 5 minutter å få de nødvendige dataene.
Bakgrunn. I dag trengte vi å behandle data om installerte programmer på brukernes datamaskiner (ja, ja, vi oppdager pirater :)). Den tekniske avdelingen ga meg denne informasjonen, strippet fra intetanende brukere over nettverket som bruker WMI. Programmet de brukte produserer rapporter i XML-format. Følgelig brakte de meg et fjell av XML-filer med en ganske kompleks struktur som jeg bare trengte å trekke ut navnet på de installerte programvareproduktene fra. Jeg har også allerede skrevet om dette, men jeg vil gjerne komme tilbake til det virkelige tilfellet med en rask analyse XML-fil
og datautvinning jeg gjorde på jobben i dag. Det tok meg ikke mer enn 5 minutter å få de nødvendige dataene.
Bakgrunn. I dag trengte vi å behandle data om
installerte programmer
på brukernes datamaskiner (ja, ja, vi oppdager pirater :)). Den tekniske avdelingen ga meg denne informasjonen, fratatt intetanende brukere over nettverket ved hjelp av WMI. Programmet de brukte produserer rapporter i XML-format. Følgelig brakte de meg et berg av XML-filer med en ganske kompleks struktur som jeg bare trengte å trekke ut navnet på de installerte programvareproduktene fra.
Behandling. Etter å ha sett gjennom et par filer manuelt, innså jeg at det ikke ville vare lenge og bestemte meg for å skrive en liten omformer. Etter å ha lansert Delphi, valgte jeg XML DataBinding-objektet i depotet og matet det med en av filene. Jeg forlot alle innstillingene og parameterne som standard, og som et resultat opprettet jeg en modul med et stort antall klasser og grensesnitt for å få tilgang til elementene i denne XML-filen. Jeg brukte ikke mye tid på å finne ut klassestrukturen og gikk umiddelbart videre til å skrive en omformer.
I den nye konsollapplikasjonen skrev jeg ganske enkel kode:
program XML2TXT;
bruker
Skjemaer,
Klasser, SysUtils,
SoftwareXML i "SoftwareXML.pas";
prosedyre CovertXML2Text;
var
CurDir:= IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
hvis FindFirst(CurDir+"*.xml", faAnyFile, sr) = 0, så
gjenta
ExportFile:= TStringList.Create;
softbase:= LoadSTDSoftware(Pchar(CurDir+sr.Name));
for i:= 0 til 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;
til FindNext(sr) 0;
slutt;
var
Application.Initialize;
CovertXML2Tekst;
slutt.
Som et resultat opprettet jeg én tekstfil for hver datamaskin i nettverket, som inneholder en liste over installert programvare.
Jeg føler at denne koden krever litt forklaring. For eksempel, hvorfor brukte jeg Forms-modulen i en konsollapplikasjon og kalte Application.Initialize-prosedyren?
Det er faktisk enkelt – det er et lite hack som lar deg bruke XML Data Binding i en konsollapplikasjon. Fordi den hardnakket nektet å initialisere klassen for å jobbe med XML. Jeg har ikke funnet ut de virkelige årsakene ennå - tiden var viktig i dag, jeg brukte allerede 4 av 5 minutter på å kjempe mot denne feilen. :) Jeg tror jeg skal finne ut av dette problemet senere og skrive hva den egentlige årsaken er.
Den merkelige softbase-klassen ble opprettet basert på en XML-fil - det var navnet på rotelementet, og softbase.InstalledSoftware.source.software[i].DisplayName - naviger ganske enkelt gjennom de nestede elementene til den ønskede og få verdien.
Dette er faktisk hvordan en av de raskeste måtene å jobbe med XML i Delphi ser ut.
Den siste tiden har det vært mye oppmerksomhet mot å bygge e-business-systemer, eller som de også kalles - B2B (business to business). Tar i betraktning anbefalingene for å bygge utvekslingsstrømmesystemer til organet som koordinerer Internett-teknologier - WWW Consortium: det legges vekt på XML-teknologier og konstruksjon av XML-dokumentutvekslingssystemer.
Fordelen med å bruke XML i elektronisk virksomhet er den høye effektiviteten til B2B-systemer til lave kostnader ved opprettelsen på grunn av en klar og visuell presentasjon av strukturert informasjon, muligheten til å bruke moderne nettverksprotokoller og lage sanntids forretningssystemer.
Uavhengigheten av å presentere informasjon i form av XML-dokumenter gjør at ulike selskaper som deltar i elektronisk virksomhet kan produsere programvare uavhengig av hverandre.
I alle systemer bygges utveksling vanligvis i henhold til samme skjema, ved hjelp av HTTP-forespørsler. SSL-protokollen brukes som en informasjonssikkerhetsprotokoll (men dette er et eget emne).
Et av de mulige alternativene for å behandle XML-meldinger er å bygge BIN/CGI (ISAPI) applikasjoner eller COM (server) komponenter som genererer eller behandler XML dokumenter.
På den ene siden fungerer applikasjonen som en klient som sender ut en HTTP-forespørsel i POST-modus, på den andre siden er det en WEB-server på siden som forespørselen behandles og svaret sendes. XML-dokumenter brukes i informasjonsutveksling.
Et av de mest effektive implementeringsalternativene er å bruke en eksisterende XML-parser som støtter DOM-modellen. Denne parseren er en distribusjonspakke av Win`98 eller en komponent av IE 4.7 og høyere (for Win`95) og representerer en COM-server som ligger i msxml.dll-biblioteket.
Component Object Model (COM) - representerer innkapslede data og metoder i en enkelt enhet og en måte å få tilgang til dem gjennom et system av grensesnitt. Ved å bruke Delphi er det ganske enkelt å få tilgang til klassene til et COM-objekt (flere klasser kan inkluderes i en COM-server). Objekter er tilgjengelige ved å initialisere en forekomst av klassen gjennom et system av grensesnitt. Beskrivelsen av grensesnitt utføres av Interface Definition Language (IDL), som kan gjøres automatisk ved hjelp av miljøet.
Delphi-verktøy importerer fra en COM-server msxml.dll, IDL-grensesnittbeskrivelsesfiler og en binær beskrivelsesfil av bibliotektyper - TLB - bygges. Denne operasjonen utføres gjennom systemmenyen: Prosjekt | Type bibliotekimport:(Figur 1). Deretter vises en dialogboks (figur 2), der du må velge et COM-objekt (i vårt tilfelle er objektet registrert under navnet "Microsoft.XMLDom (versjon 2.0)") og opprette en TLB-fil (knapp). Opprett enhet). Ved å bruke TLB-filen genererer miljøet en "Pascal" COM-serverbeskrivelsesfil - MSXML_TLB.pas
MSXML_TLB.pas-filen beskriver alle grensesnitt, konstanter og co-klasser til COM-serveren.
For å få tilgang til COM-elementobjekter er det nødvendig i direktivet BRUK legg til navnet på bibliotekbeskrivelsesfilen (MSXML_TLB.pas). Nedenfor er et enkelt program som bruker standard DOM-parser msxml.dll, som laster et XML-dokument og viser det i Memo1-tekstfeltelementet.
bruker Windows, meldinger, SysUtils, klasser, grafikk, kontroller, skjemaer, dialogbokser, OleServer, MSXML_TLB, StdCtrls; type TForm1 = klasse(TForm)-knapp1: TB-knapp; Memo1: TMemo; prosedyre Button1Click(Avsender: TObject); slutt; var Form1: TForm1; implementering ($R *.DFM) Prosedyre TForm1.Button1Click(Sender: Emne); slutt;// erklæring av en koklasse for DOMDocument-objektet; coDoc: CoDOMDocument; slutt;// klasse i samsvar med IDOMDocument-grensesnittet; Dokument: IXMLDOMDocument; begynne// opprette en forekomst av et DOMDocument-objekt; Doc:= coDoc.Create;// kaller Load-metoden til en DOMDocument-objektforekomst; Doc.load("data.xml");// tilgang til xml-egenskapen til DOMDocument-objektforekomsten; Memo1.Text:=Doc.xml; slutt;slutt.
Hvert XML-dokument er representert som et sett med mange objekter (klasser), ved hjelp av hvilke tilgang til individuelle elementer (objektfelt) er mulig. DOM - grensesnitt beskriver tilgang til både enkle objekter av typen DOMString eller CharacterData, og til deler eller individuelle elementer av et XML-dokument: DOMFragmentElement, DOMNode, DOMElement.
Nedenfor er de viktigste egenskapene og metodene til XMLDOMNode, XMLDOMNode, XMLDOMNodeList-objektene. Det skal bemerkes at metodene og funksjonene til DOM-objekter (Document Object Model) som presenteres nedenfor, brukes av Microsoft XML-parseren msxml.dll og er noe bredere enn DOM-modellen godkjent av W3C Consortium.
En mer fullstendig beskrivelse av DOM-objektgrensesnittet finner du på
XMLDOMDocument-objekt | |
Representerer det øverste nivået i objekthierarkiet og inneholder metoder for å jobbe med et dokument: laste det, analysere det, lage elementer, attributter, kommentarer i det, etc. . | |
Egenskaper | |
Asynkron | Egenskap som identifiserer gjeldende behandlingsmodus |
ParseError | Returnerer en referanse til XMLDOMParseError-feilhåndteringsobjektet |
Aktiver - deaktiver dokumentverifisering. | |
url | Returnerer URL-en til dokumentet |
documentElement | Inneholder en referanse til rotelementet til dokumentet som et XMLDOMElement-objekt. |
Metoder | |
last (url) lastXML(xmlString) |
Laster et XML-dokument, |
save(objTarget) | Lagrer et XML-dokument til en fil |
abort | Avbryter lasting og behandling av dokumenter. |
createAttribute(name) | Oppretter et nytt attributt med det angitte navnet for det gjeldende elementet. |
createNode(Type, navn, navnSpaceURI) | Oppretter en node av den angitte typen og navnet |
createElement(tagName) | Oppretter et dokumentelement med det angitte navnet. |
createTextNode(data) | Oppretter tekst inne i et dokument |
getElementsByTagName(tagnavn) | Returnerer en referanse til en samling dokumentelementer med gitt navn |
nodeFromID(idString) | Søker etter et element etter ID |
XMLDOMNode-objekt | |
Et XMLDOMNode-objekt som implementerer det grunnleggende DOM-grensesnittet Node, er ment for å manipulere en enkelt node i dokumenttreet. Egenskapene og metodene lar deg få og endre fullstendig informasjon om gjeldende node - dens type, navn, fullt navn, innhold, liste over underordnede elementer, etc. | |
Egenskaper | |
nodenavn, basenavn | Returnerer navnet på gjeldende node. |
prefiks | Returnerer navneområdeprefikset. |
datatype | Bestemmer innholdstypen til gjeldende node |
nodeType, nodeTypeString | Returnerer typen til gjeldende node: |
attributter | Returnerer en liste over attributter for gjeldende node som en samling av XMLDOMNamedNodeMap. |
tekst | Returnerer innholdet i det gjeldende undertreet som tekst |
xml | Returnerer en XML-representasjon av gjeldende undertre. |
nodeverdi | Returnerer innholdet i gjeldende node. |
barnnoder | Returnerer en liste over underordnede elementer som en XMLDOMNodeList. |
førstebarn, sistebarn | Returnerer det første/siste underordnede elementet |
forrigeSøsken ,nesteSøsken | Returnerer forrige/neste søskenelement. |
parentNode | Inneholder en lenke til det overordnede elementet. |
eierDokument | Returnerer en peker til dokumentet der den gjeldende noden er plassert. |
Metoder | |
appendChild(newChild) | Legger til et nytt underordnet element til gjeldende node. |
insertBefore(newChild, refChild) | Setter inn en underordnet node, og plasserer den i det gjeldende undertreet "til venstre" for noden spesifisert av refChild-parameteren. |
cloneNode (dyp) | Lag en kopi av det gjeldende elementet. |
getAttribute(navn) getAttributeNode(navn) setAttribute(navn, verdi) setAttributeNode(XMLDOMAttribute) |
Tilgang til attributter (opprette, lese, skrive) til et objekt. Navn er navnet på attributtet, verdi er verdien. Returnerer verdien til et XMLDOMAttribute-objekt. |
replaceChild(newChild, oldChild) removeChild(oldChild) | Erstatter oldChild-objektet i gjeldende liste over underordnede objekter med newChild. Sletter oldChild-objektet |
selectNodes(patternString) selectSingleNode(patternString) | Returnerer XMLDOMNodeList-objektet valgt av søkemønsteret eller den første noden |
transformNode(stilark) transformNodeToObject(stilark, outputObject) |
Tildeler et stilark til undertreet til gjeldende node og returnerer en streng - resultatet av behandlingen. En referanse til DOMDocument-objektet som inneholder XSL-instruksjoner sendes som en parameter. |
Bruke XML i virksomheten.
For et klarere bilde er det nødvendig med en forklaring på hvorfor alt dette er nødvendig for å forstå hvordan det fungerer:
Når du bygger et B2B- eller bedrifts-ERP-system, når du organiserer informasjonsutveksling av XML-dokumenter mellom bedrifter eller filialer av et selskap, brukes et effektivt utprøvd informasjonsoverføringssystem basert på eksisterende WEB-servere via HTTP-protokoller.
På den ene siden fungerer applikasjonen som en klient, som utsteder en HTTP-forespørsel i POST-modus, på den andre siden er det en WEB-server, på hvis side forespørselen behandles og svaret utstedes. XML-dokumenter brukes som utveksling.
For eksempel, i et enkelt bedrifts-ERP-system, må et regnskapsprogram (ASU Bukhuchet) generere en bestemt forespørsel om å utstede en faktura og overføre den til en filial som har et lager (ASU Warehouse). AWP En lignende formulering av problemet når du oppretter et B2B-system, når Enterprise A ber om tilgjengelighet av produkter (legger inn en innkjøpsordre) fra leverandør B.
Enterprise A og dets program fungerer som en klient. Lageret betjenes av leverandør B, som har et lagerdatabasekompleks på en SQL-server. Utvekslingen utføres gjennom bedriftens WEB-server til Leverandør B.
Følgende typiske utvekslingsalgoritme er presentert nedenfor:
Figur 3.
- Enterprise A initierer prosess A(produktordre), som fungerer som WEB-klient.
- Prosess A genererer et XML-dokument (for eksempel en fakturaforespørsel) og overfører det som en POST http-forespørsel til WEB-serveren til leverandør B. Ressursidentifikatoren til behandlingsapplikasjonen brukes som en URI. URI-en kan være den samme for alle typer dokumenter, eller individuell for hver type. Alt avhenger av strukturen til B2B (WEB) serveren.
- WEB-server analyserer forespørselen og genererer en server Prosess B, ved å sende teksten til XML-dokumentet som en parameter.
Prosess B startes av WEB-serveren og behandles enten som en ASP-side, en CGI (ISAPI)-applikasjon eller en JAVA-serverlet (serverapplikasjon) - Prosess B- genererer en forespørsel til SQL-databasetjeneren.
- SQL-serveren utfører de nødvendige operasjonene i databasen, genererer et svar og returnerer det Prosess B.
- Basert på svaret fra SQL-serveren Prosess B genererer et XML-dokument (svar) og returnerer det som et svar på en http-forespørsel til klientapplikasjonen.
- Deretter, avhengig av situasjonen på klientsiden, genereres enten en ny http-forespørsel eller økten avsluttes.
Noen få ord om organiseringen av dokumentflyt.
Den generelle regelen for å utvikle et XML-dokumentutvekslingssystem er:
- For det første- utvikling av et flytdiagram av elektroniske dokumenter og deres struktur;
- for det andre- utvikling av tabeller over prosessfunksjoner (delprosesser), dvs. hvilken funksjon i forhold til hvilket XML-dokument hver prosess skal implementere.
Hvert XML-dokument, som et HTML-dokument, må bestå av en meldingshode (informasjon omsluttet av tagger) og en meldingstekst (for en forespørsel er denne informasjonen vedlagt tagger for å svare på forespørselen). For at XML-dokumentet skal være riktig utformet, er det nødvendig å ramme de to komponentene "Header" og "Request" med tagger, for eksempel. Typen standarddokument er presentert nedenfor:
Overskriften (Figur 4), i motsetning til et HTML-dokument, må inneholde ulike typer tjenesteinformasjon, inkludert informasjon om typen dokument som overføres og prosessen med behandlingen. Brødteksten i dokumentet går inn i informasjonsbehandling, dvs. innhold innrammet med tagger. Det skal bemerkes at strukturen av overskrifter må være den samme for alle typer dokumenter.
For en prosess lansert av serveren, er behandlingsalgoritmen fortrinnsvis (men ikke nødvendigvis) konstruert som følger:
Figur 6.
Noen grunnleggende punkter når du oppretter klientdelen
Som allerede forklart, når du oppretter et XML-dokument, brukes dets representasjon i form av en DOM-modell. Nedenfor er et eksempel på en del av Delphi-teksten til programmet for å lage en xml-meldingshode.
Memo1: TMemo; TThread1.HeaderCreate(Avsender: Emne); slutt; // erklæring om en coclass, nødvendig for å opprette coDoc: CoDomDocument; // XMLDomDocument-objekt Dok.: DomDocument; Dokument: IXMLDOMDocument; r: IXMLDOMElement; Node: IXMLDOMElement; // DOMText txt: IXMLDOMText;// DOMAttribute attr: IXMLDOMAttribute;// lignende operasjoner for tag
Til
Figur 5.
Figur 6.
Hovedfordelen med å overføre informasjon i form av XML-dokumenter er at det er mulig å generere en melding ved å bruke uavhengige tabellstrukturer i DBMS både på mottaker- og sendersiden. Ved å bruke vårt eksempel, la oss anta at vi trenger å overføre informasjon om fakturaer til Enterprise A fra et DBMS med strukturen vist i figur 6
For å generere et xml-dokument som inneholder en faktura, bygges en SQL-spørring (spørring A) i utgangspunktet med informasjon om selve fakturaen:
VELGE* FRA Faktura_Generelt HVOR InvoiceNum = :num VELGE Varer,Kvalitet,Pris, HZ_cod FRA Varer HVOR InvoiceNum = :num // :num - parameter som spesifiserer fakturanummeret.Nedenfor er en del av programmet som utgjør hoveddelen av xml-dokumentet:
Memo1: TMemo; TThread1.DataBodyCreate(Sender: Tobject); slutt; // erklæring av en coclass og et XMLDomDocument-objekt//coDoc: CoDomDocument ; // må være global for hele modulen.//Dok: DomDocument ; // erklæring av DOMElement-objekter r: IXMLDOMElement; // DOMElement; Node, Node2: IXMLDOMElement; Node3, Node4: IXMLDOMElement; // DOMText txt: IXMLDOMText; str: String; Dokument: IXMLDOMDocument;// Fakturanummer: heltall;- global variabel - // har verdien 987654 // queryA, queryB: streng;- global variabel, // har en verdi som tilsvarer forespørselen // queryA - request A generell informasjon om fakturaen // queryB - request B informasjon om varene beskrevet i // fakturaen (se tekst) Query.Close;// se teksten "spørring A" Query.Text:= queryA;// utfør forespørselen Query.ExecSQL; Query.Open; // får adressen til rotelementet r:=Doc.Get_documentElement; Query.Text:= queryA; Node2:= Doc.createElement("Request"); // får adressen til rotelementet// opprette DOMElement (tag) Node:= Doc.createElement("Faktura");// legge til et element til roten r.appendChild(Node2);// legge til et element til Node 2. appendChild(Node); LLC "Tyfon" Node3:= Doc.createElement("Depurture");Node.appendChild(txt);
... // lignende operasjoner for tagger:
Memo1: TMemo; Som et resultat av denne prosedyren genereres følgende tekst i XML-dokumentet:For å lage en forespørsel, brukes Open-metoden for objektet
IXMLHttpRequest
Open(const bstrMethod, - metodetype ="POST" bstrUrl, - URL-serveradresse varAsync, - kommunikasjonsmodus asynkron/synkron = true bstrUser, - brukernavn for autentisering bstrPassword) - passord
Memo1: TMemo; Opprette en dokumentbehandlingsserverdel slutt; Som nevnt tidligere kan behandling av HTTP-forespørsel gjøres av enten CGI-applikasjoner eller Java-servlets. Det er også mulig å skrive ASP-sider. Men i dette tilfellet er dataoverføring bare mulig ved å bruke "GET"-metoden via en spørringsstreng. Selv om HTTP-forespørselsbehandling for ASP-sider er mer effektiv enn for en CGI-applikasjon. Men etter min mening spiller det ingen rolle hvordan man behandler, men det som er viktigere er å løse spørsmålet - hvordan bygge et behandlingsprogram, og ikke med hvilke midler. Hvis vi fra forrige kapittel så på alternativer for å generere et XML-dokument, så er oppgaven til serverapplikasjonen det motsatte - å analysere XML-dokumenter. Nedenfor er en del av programmet som analyserer xml-dokumentet: Tthread1.DataParser(Sender: Tobject);// erklæring av DOMElement-objekter r,FNode: IXMLDOMElement; Str, Filnavn: String; parm: String; // erklæring om en medklasse og CoDocXML, CoDocXSL, CoDocResult: CoDomDocument ; Query.Close;// XMLDomDocument-objekt XMLDoc, XSLDoc, ResultDoc: DomDocument ;// HttpStr: String; - global variabel som inneholder HTTP-forespørselsstrengen Begynne XMLDoc:=coDocXML.Create; XMLDoc.LoadXML(HttpStr); r:=Doc.Get_documentElement; // får elementets verdi FNode:= r.SelectSingleNode("//TypeDocument"); // får attributtverdien id="Order" ResultDoc:=coDocResult.Create; // innstilling av synkron behandlingsmodus ResultDoc.Set_async(false); // sett parsing sjekk ResultDoc.validateOnParse:= sant; // analyser XMLDoc ved å bruke en XSL-mal XMLDoc.transformNodeToObject(XSLDoc, ResultDoc); // variabel Str er tildelt en tekstverdi // det resulterende dokumentet. Str:= ResultDoc.text; // søk etter element FNode:= r.SelectSingleNode("//InvoiceNumber"); // og få elementets verdi parm:= FNode.tekst; // lukker tilgangsforespørselen Query.Close; Query.Text:= Str;// tilordne en parameterverdi streng; Query.Params.AsString:= parm; Memo1.Text:=Doc.xml;Query.ExecSQL;
Hele høydepunktet i analysen er bruken av en XSL-mal, som genereres individuelt for hver type dokument. Resultatet av parsing er en SQL-spørringsstreng. Deretter vil kjøring av den genererte SQL-spørringsstrengen gjøre de nødvendige endringene i dataene i DBMS.
SETT INN i VARER (fakturanummer, navn, pris, kvalitet) VERDIER(" :antall", "
For å forklare eksemplet ovenfor, bør det bemerkes at bruken av et par tagger er av formell karakter, fordi etter parsing må det resulterende XML-dokumentet formelt inneholde minst én node. ResultDoc.text-metoden tildeler tekstverdien til ResultDoc XML-dokumentet innhentet under parsing. I dette tilfellet er verdien alt som er innrammet av et par tagger og, dvs. SQL-spørringen vi genererte. En annen funksjon ved å skrive et program bør bemerkes muligheten for å bruke en SQL-parameter:nummer.
Ved å bruke denne parameteren kan du forenkle teksten til xsl-malen. Å bestemme betydningen av de tilsvarende nodeelementene i et XML-dokument bestemmes ved først å velge navnet på den tilsvarende noden, for eksempel:
Kort om XSL
- Forkortelsen XSL kommer fra eXtensible Stylesheet Language – et språk for formatering av stilark (XML-data). Som tittelen antyder, brukes eXtensible Stylesheet Language (XSL) til å formatere XML-data. Etter W3C-definisjon består XSL av to deler:
- Formatering av elementer. Disse elementene inkluderer alle elementer i den typografiske utformingen av dataene, etter at de har blitt behandlet med XSL. Brukes kun til å generere HTML-sider.
Ved hjelp av XSLT kan vi velge dataene vi trenger fra en XML-fil og ordne dem i et skjema for presentasjon for brukeren. For eksempel, i vårt tilfelle konverterte vi XML-data til en SQL-spørring. Den klassiske bruken av XSL er som regel å formatere data i form av HTML-sider eller, mer sjelden, i form av RTF-filer.
XSL-filen beskriver malen som XML-dataene skal konverteres etter. Når vi går tilbake til xsl-maler, kan følgende elementer (direktiver) skilles fra hverandre i XSLT:
XSL-direktiver | beskrivelse |
---|---|
xsl:apply-maler | Direktiv som indikerer bruken av de tilsvarende malene på select="malnavn"-attributtet |
xsl:attributt | oppretter et attributtre og legger det til utdataelementet, parameter name="attribute name", navneområde - URI til navneområdet (navneområdeprefiks) |
xsl:anropsmal | kaller malen, attributt name="URI til mal" |
xsl:velg xsl:når xsl:ellers |
gjøre et valg basert på xsl:when expr="evaluere et uttrykk i et skript", language="språknavn" test= "evaluert uttrykk" |
xsl:kommentar | genererer en kommentar i utdatadokumentet |
xsl:kopi xsl:kopi av |
kopierer gjeldende node til utdatakilden eller limer inn et dokumentfragment i noden der select-attributtet = "kildenodenavn" |
xsl:element | oppretter et utdataelement etter navn, attributt name="elementnavn", namespace="uri navneområdereferanse" |
xsl:for-hver | bruker malen på nytt på alle noder i nodelisten, select-attributtet spesifiserer listen over noder |
xsl:if | sjekke betingelsen, spesifisert av testattributtet som et uttrykk |
xsl:inkluder | inkluderer ekstern mal, href = "URI-referanse"-attributt |
xsl:utgang | spesifiserer utdataresultatet, metodeattributtet kan ha verdiene "xml", "html" eller "tekst" |
xsl:param | spesifiserer verdien av parameterne, attributtnavn="parameternavn", velg = "verdi" |
xsl:behandlingsinstruksjon | oppretter en behandlingsinstruksjon, attributt name="prosessinstruksjonsnavn" |
xsl:sort | sorterer flere noder, attributter select = "nodenavn", datatype = datatype ("tekst" | "nummer" | Qname), rekkefølge = sorteringsretning ("stigende" | "synkende") |
xsl:stilark | definerer et xsl-maldokument, er rotelementet for XSLT |
xsl:mal | definerer en xsl-mal, attributt name= "URI-prefiks til malnavnet", match= "indikasjon på noden som malen brukes på" |
xsl:tekst | genererer tekst inn i utdatastrømmen, disable-output-escape-attributtet = "yes" eller "no", indikerer muligheten til å generere ESC-tegn |
xsl:verdi-av | setter inn verdien til den valgte noden som tekst, select-attributtet = "peker til node" som verdien er hentet fra |
xsl:variabel | spesifiserer verdien av variabelgrenser, attributtnavn = "variabelnavn", velg = "beregning av variabelverdi" |
xsl:with-param | bruker en parameter på en mal, navneattributt = "parameternavn", velg = uttrykk for å evaluere gjeldende kontekst, standardverdi "." |
Konklusjon
Til slutt bør det bemerkes at bruk av en standard XML-parser msxml.dll er ikke det eneste verktøyet for å analysere og lage XML-dokumenter. For å lage XML-dokumenter er det for eksempel effektivt å bruke komponenter TPageProduser Og TTableProduser. Men denne artikkelen understreker bare bredden og muligheten for å bruke DOM-modellen i praksis.
Forfatteren vil være veldig takknemlig for tilbakemeldinger om relevansen til emnet, generelt innhold, presentasjonsstil, så vel som alle andre kommentarer som vil bidra til å forbedre kvaliteten på å skrive en samling artikler og utgivelsen av en bok som dekker emnet ytterligere. av den praktiske siden ved bruk av XML-dokumenter i e-handel. Mer detaljert informasjon om den praktiske siden ved bruk av elektroniske dokumenter finnes på forfatterens nettsted www.eDocs.al.ru Det er også planlagt å legge ut kildetekster og eksempler på forfatterens nettsted.
Hvordan jobbe