|
Man har til tider brug for at arbejde med datastrukturer, men har ikke adgang til en database eller brugen af databasen er for langsom til at håndtere den opgave man skal løse. Et alternativ til databasen, hvor man stadig har stærke opslagsmuligheder, er XML-DOM. Med hjælp fra MSXML2.DOMDocument kan XML-data opbevares i hukommelsen og aflæses efter behov. Desuden kan man koble XSLT på og få en effektiv omsætning af data til præsentation (eller hvordan man nu ønsker at levere sine data). Denne artikel kommer dog ikke ind på XSLT, men holder sig til at beskrive de basale funktionaliteter i DOMDocument, så du bliver i stand til at navigere rundt i DOM'en, samt oprettet, flytte, ændre og nedlægge elementer heri. Artiklen i overblik
Oprettelse af XML DOMForudsat komponenten er installeret på serveren, kan man oprette et XML DOM-objekt med flg. kode: dim xmldoc Indæsning af XML dokumenterXML dokumentet kan indlæses på to måder, enten ved at angive et XML-dokument i en streng eller ved at angive stien på en fil der indeholder et XML-dokument. Følgende demonstrerer de to metoder. Indlæsning via en streng, hvor der er defineret et rodelement ved navn root og et underelement ved navn data: xmldoc.loadXML "<root><data/></root>" Indlæsning via en fil, som i princippet kan have det samme indhold som ovenfor: xmldoc.load Server.MapPath("/xmldata/datadoc.xml") Her er xml-dokumentet så placeret i en mappe (der ligger i roden af websitet). Dokumentet hedder datadoc.xml. Validering af XML dokumenterDet er en god ting at sikre sig, at det dokument man lige har indlæst er validt, så derfor bør man checke om der er parserfejl i forbindelse med indlæsningen: if xmldoc.parseerror.errorcode = 0 then Oprettelse af elementerNår man så har fået indlæst sit XML-dokument, kan man begynde at manipulere det og det første jeg vil demonstrere er oprettelse af nye elementer. Jeg vil gerne have oprettet et nyt data-element under rod-elementet i mit dokument (så der ligger to, hvis vi tager udgangspunkt i den indlæste XML-streng tidligere i denne artikel). Således XML-strukturen kommer til at se således ud: <root><data/> <data/> </root> Dette kan jeg komme afsted med, ved at gøre således: dim datanode Den korte udgave ville have set således ud: xmldoc.documentElement.appendChild xmldoc.createElement("data") Den korte udgave kan bruges, hvis jeg ikke umiddelbart ønsker at arbejde videre med det nye data-element. Hvis jeg ønsker at arbejde videre med det nye data-element, kunne jeg tilpasse den korte version lidt: set datanode = xmldoc.documentElement.appendChild(xmldoc.createElement("data")) da appendChild returnerer det nye element som tilføjes den aktuelle node. documentElement er i øvrigt en node på linie med alle andre noder i XML-strukturen, der må blot kun være netop én node i roden af et XML-dokument - ellers er det ikke validt. Undtaget er dog processing instructions og kommentarer som gerne må forekomme i roden (processing instructions skal, såvidt jeg ved, ligge i roden). CDATA-elementer til større tekstblokkeHvis man arbejder med fritekster, dvs. længere tekster som typisk også kan indholde specielle tegn, så som < > & osv. så er CDATA nok det XML-element der klarer opgaven bedst. Sådan en kan oprettes med en speciel funktion og det ser således ud (jeg tager udgangspunkt i at den sidste datanode jeg tilføjede dokumentet ovenfor skal indeholde dette CDATA-element): dim teksten Dette vil, under antagelse af at vi bygger videre på det ovenfor genererede XML, producere et XML-dokument som ser således ud: <root> Skal jeg så have fat i disse oplysninger igen, kan jeg f.eks. aflæse firstChild.data på det data-element som indeholder CDATASection-elementet: teksten_var = datanode.firstChild.data Jeg vil senere komme mere ind på hvordan man finder elementer i XML-dokumentet. Manipulering af elementers atributterSelvom man kan beskrive meget struktur og data blot ved hjælpe af XML-elementer, som root og data i eksemplerne ovenfor, så er nogle oplysninger bedre egnet til at blive gemt i atributter. Det er typisk data som har en begrænset udstrækning, så som tal, datoer og korte tekster, hvor der ikke forekommer linieskift (muligvis også visse specialtegn, jeg dog lidt usikker på hvilke der helt præcis giver problemer i atributter). Ønsker man at sætte en værdi i en atibut, kan man benytte flg. metode: datanode.setAttribute "id", "100" Findes atributten i forvejen opdateres værdien og findes den ikke oprettes atributten med den angivne værdi. I ovenstående tilfælde ville XML-dokumentet komme til at se således ud efterfølgende: <root> Tilsvarende let er det at læse en atribut ved at kalde metoden getAttribute på det aktuelle XML-element: id = datanode.getAttribute("id") Hvis atributten ikke findes på elementet, returneres en tom streng, ellers returneres værdien af atributten. Flytning af elementerI XML giver det ikke mening at ordne elementer som er sidestillede under samme forælder-element, da XML standarden foreskriver at sekvensen af elementer aldrig kan garanteres. Men der kan stadig være behov for at flytte rundt med elementer op og ned eller sideværts (til et andet forælder-element) og til dette formål har vi appendChild og removeChild. Hvis vi skal flytte et element fra ét element til et andet, skal vi altså benytte removeChild og appendChild således: dim parent, child Det skulle gerne resultere i følgende XML-struktur: <root>
Udskiftning af elementerTil tider kunne man have brug for at redigere et element uden at det afspejler sig i XML-dokumentet mens man redigerer. Til dette formål kan man benytte en kombination af clodeNode og replaceChild. clodeNode tager en kopi af det element man kalder den på, evt. med alle underelementer, og returnerer dette som et nyt XML-element. Dette element kan man rette i og til sidst udskifte det element man klonede i første omgang, med det man har rettet. På denne måde kan man håndtere et niveau af "undo". Et eksempel kunne se således ud: dim datanode Det vil resultere i følgende XML-struktur: <root>
Fjernelse af elementerØnsker man at fjerne XML-elementer fra sin XML-struktur, kan man som vist tidligere benytte removeChild. Man skal blot have fat i det element man ønsker at fjerne, samt dette elements forælder-element, inden man kan fjerne elementet. Heldigvis er det nok bare at få fat i selve elementet man vil fjerne, da det selv kan pege på sit forælder-element (via egenskaben parentNode). Det kunne altså se således ud, hvis man ville fjerne et XML-element fra strukturen: dim datanode XML-strukturen ville herefter komme til at se således ud: <root>
Arbejde med lister af elementerIndtil nu har vi kigget lidt på hvordan man får fat i et enkelt element og arbejder med dette, men vores muligheder udfolder sig først rigtigt, når vi begynder at arbejde med sæt af data. DOMDocument har en type som hedder XMLDOMNodeList (det er en collection). Denne indeholder 0 til mange XMLDOMNode-objekter, som f.eks. data-elementet fra ovenstående struktur. Denne liste kan man iterere, som man også kan med arrays og andre collections, med "for each"-løkken. Lad os kigge lidt på hvordan dette kan tage sig ud. Vi antager at vi har følgende XML-struktur indlæst i xmldoc: <root> Vi kan så gennemløbe alle elementer under roden (root-elementet) med følgende stump kode: dim nod Det skulle gerne resultere i følgende output: navn = Ulla Terkelsen Vi ser altså at childNodes er en XMLDOMNodeList som kan itereres og hver iteration giver os hver af de elementer som findes i listen og vi kan arbejde med dem som tidligere beskrevet, altså manipulere og aflæse indholdet af en node og dens atributter, samt dens under-elementer (efterkommere). Vær forsigtig med at slette elementer i forbindelse med iteration af en nodeliste, da dette kan "forvirre" den iterator der styrer iterationens placering i listen. Det er muligvis ikke et problem, men vær opmærksom på at få testet det grundigt, hvis du kaster dig ud i at ændre grundlaget for udvælgelsen af listens indhold, dvs. tilføjer, flytter eller sletter elementer under ejer-elementet af den childNodes der itereres! Søgning i dokumentet med XPathEt af de steder hvor styrken af XML-dokumentet (XMLDOM'en) rigtig viser sig, er når man tager hul på XPath. XPath er søgning i XML-strukturen med et sprog der omfatter basale funktioner til håndtering af strenge, tal, booleske værdier, samt opsætning af betingelser til navigation i XML-strukturen via nogle akse-operatorer. En akse-operator beskriver den sti der skal følges i søgningen af XML-elementer. Det kunne f.eks. være forfædre, forældre, søskende, børn, efterkommere. Der er forskellige notationer som skal overholdes og jeg vil ikke gå i dybden med XPath her, men blot vise nogle eksempler på nogle basale søgninger. Du kan selv undersøge XPath-universet på internettet... Inden jeg begynder at demonstrere XPath vil jeg lige definere en, strukturmæssig, lidt mere interessant XML-struktur, som giver lidt muligheder for at demonstrere noget af det XPath kan. Mit setup tager udgangspunkt i et medlemskartotek til en lille klub, hvor oplysninger om medlemmer og hold gemmes. Det kunne se således ud: <root> Så er vi klar til at lave nogle opslag i vores XML-struktur, som kunne have en vis relevans for en sportsforening der baserer sig på holdsport :-) Først kunne vi jo starte med at generere en holdliste for mesterholdet. Det kan gøres på flere måder. Vi kan f.eks. vælge medlemmer som er tilknyttet et hold med et bestemt holdid (hvis det er holdid'er vi kender på forhånd) og det kunne se ud som vist nedenfor. Det antages at xmldoc er en global variabel som indeholder XML-dokumentet med ovenstående struktur, så jeg springer bare direkte ud i det: function findHoldMedlemmer(holdid) Ovenstående funktion vil returnere en nodeliste (en liste med 0 til mange XMLDOMNode-objekter) med alle de medlemmer der matcher et kriterium om at deltage på det angivne hold. En anden forespørgsel kunne finde os de hold som træner på en onsdag: function findHoldTraeningsdag(traeningsdag) Herefter indeholder variablen holdliste de hold som har traeningsdag på en onsdag, dvs. "mesterholdet". Der kan bruges meget mere tid på at snakke om XPath og det sæt af funktioner som følger med, men i denne artikel vil jeg stoppe her og nøjes med at have vækket din interesse for mulighederne i brugen af XML i forbindelse med ASP og VBScript (eller et hvilket som helst andet sprog der kan arbejde med COM-objekter). Der findes mange bøger i boghandlen og sider på internettet der går i dybden med XML, XPath og hvad teknologierne omkring XML hedder, så hvis du synes dette er interessant, så er det bare at komme igang med at søge... God fornøjelse!
|
| Sidst opdateret: 16-06-2009 12:22:02 |
|
Tilmeld link |
Tilføj Link |
Tilføj Link |
@-begynder Erklæring om beskyttelse af personlige oplysninger |