19. august 2005 - 09:08Der er
8 kommentarer og 1 løsning
Hent værdier enkeltvist fra XML-fil
Hej
Jeg er lige startet med at eksperimentere med XML, og vil prøve at indlæse en simpel XML-fil for at gemme værdierne i en database.
Min kode ser sådan ud:
Set objXML = Server.CreateObject("Microsoft.XMLDOM") objXML.async = False objXML.Load strPath
Set objRootElement = objXML.documentElement
For i = 0 to objRootElement.childNodes.Length - 1 response.Write objRootElement.childNodes.item(i).Text & "<br>" response.Write objRootElement.childNodes.item(i).NodeName & "<br>" Next
Når jeg prøver at skrive outputtet ud, så ser det sådan ud: 10029 Den individuelle udviklingsplan 2900 khoved 10030 YYY1 1200 khoved 10031 BudgTest 550 khoved
Jeg har behov for at få fat i de 3 elementer enkeltvist, så jeg derved kan gemme det i databasen, men jeg kan kun få dem vist i én streng (.text).
For en XML-haj er dette sikkert et helt banalt spørgsmål, men jeg skal jo lige i gang ;-)
Når jeg prøver at skrive outputtet ud, så ser det sådan ud: 10029 Den individuelle udviklingsplan 290 khoved 10030 YYY1 120 khoved 10031 BudgTest 55 khoved
Det er fordi .Text viser hele indholdet af en node (inklusiv undernoders tekst). Du skal benytte nodeValue i stedet, så burde du få selve nodens tekst uden undernoder.
Tip: Jeg vil varmt anbefale at du kaster dig over XPath, da det superlækkert at finde data med i en XML-fil. XPath kan bla. benyttes i samspil med funktionerne selectSingleNode (som finder en enkelt node) og selectNodes (som finder en mængde noder). XPath er kort fortalt XML'ens SQL-sprog, dvs. til at lave forspørgsler i en XML-struktur.
Du kan f.eks. finde alle khoved-noder der ligger under ROOT ved at skrive:
objRootElement.selectNodes("/ROOT/khoved")
eller alle khoved-noder hvor khoved_id = 10030 ved at skrive:
Jeg har eksperimenteret lidt med din råd, men det giver mig desværre ikke de værdier jeg har behov for.
Jeg har behov for <element> og <værdi>. F.eks.:
"khoved_id" og "10029" "khoved_navn" og "Den individuelle udviklingsplan" "khoved_prisprdeltager" og "290"
Dette for hver eneste "khoved"-element. NodeValue giver mig bare en tom linie, og objRootElement.selectNodes("/ROOT/khoved") giver mig følgende fejl: "Antallet af argumenter er forkert eller egenskabstildelingen er ugyldig"
Kan du evt. se hvad jeg skal tilrette i mit FOR-LOOP for at få de ønskede værdier ud, så jeg kan gemme dem i en database?
Hmm... jeg har lige kigget lidt på en konkret test af noget kode og det lader til at jeg ikke forstår dokumentationen mht. nodeValue. Det er der dog råd for, for jeg kan stadig bruge text-egenskaben på leaf-noder til at hente tekst ud af en node. Det betyder at jeg kan finde de værdier du efterspørger på flg. måde:
dim objXml, objRoot dim strPath
strPath = Server.MapPath("testXml.xml")
set objXml = Server.CreateObject("Microsoft.XMLDOM") objXml.Load strPath
set objRoot = objXml.documentElement
set objNodLst = objRoot.selectNodes("/ROOT/khoved") for each objNod in objNodLst Response.Write("khoved: <br>") Response.Write(" khovednavn: " & objNod.selectSingleNode("khoved_navn").text & "<br>") Response.Write(" khovedpris: " & objNod.selectSingleNode("khoved_prisprdeltager").text & "<br>") next
Ok, det lader til at man skal benytte nodeTypedValue i stedet for nodeValue. Dvs. koden ovenfor kan skrives således:
dim objXml, objRoot dim strPath
strPath = Server.MapPath("testXml.xml")
set objXml = Server.CreateObject("Microsoft.XMLDOM") objXml.Load strPath
set objRoot = objXml.documentElement
set objNodLst = objRoot.selectNodes("/ROOT/khoved") for each objNod in objNodLst Response.Write("khoved: <br>") Response.Write(" khovednavn: " & objNod.selectSingleNode("khoved_navn").nodeTypedValue & "<br>") Response.Write(" khovedpris: " & objNod.selectSingleNode("khoved_prisprdeltager").nodeTypedValue & "<br>") next
Bemærk at jeg specifikt benytter selectSingleNode til at hente childnodes, da jeg ikke kan være 100% sikker på at de altid ligger i samme rækkefølge under khoved (det er bare sådan en indgroet livrem-og-seler-politik jeg har antaget med årene :)).
Du skal dog være opmærksom på at koden til fejle noget så grusomt hvis enten khoved_navn eller khoved_prisprdeltager ikke findes under khoved! Det kan der dog checkes for:
if not objNod.selectSingleNode("khoved_prisprdeltager") is nothing then Response.Write(" khovedpris: " & objNod.selectSingleNode("khoved_prisprdeltager").nodeTypedValue & "<br>") end if
Man kan naturligvis også iterere childnodes og så checke på nodeName for hver enkelt node under en node, men jeg kan bedre lide den direkte tilgang til data, når jeg ved hvad jeg leder efter (jeg har sådan en følelse i maven der siger mig at det performer bedre :))...
Eksempel: for each objNod in objNodLst Response.Write("khoved: <br>") for each objChild in objNod.childNodes if objChild.nodeName = "khoved_navn" or objChild.nodeName = "khoved_prisprdeltager" then Response.Write(" " & objChild.nodeName & ": " & objChild.nodeTypedValue & "<br>") end if next next
I øvrigt er den heller ikke praktisk hvis man skal hente værdier fra mange felter (selvom jeg kunne finde mere effektive metoder at undersøge om feltnavnet skal bruges, f.eks. instr på en streng der indeholde feltnavnene).
Det var lige præcist dette jeg var ude efter :-D Jeg har nu de værdier fra XML-filen jeg skal bruge for at arbejde videre med dem i en database.
Kan man evt. også aflæse elementet, så jeg søger gennem alt der ligger under \ROOT\khoved, så jeg kan læse både selve navnet på elementet (f.eks. "khoved_id"), og så den tilhørende værdi (som du allerede har vist mig hvordan jeg læser) ?
Vil du poste som et svar, så jeg kan give dig lidt point?
Tusinde mange tak for hjælpen, Softspot. Det var pænt af dig :-)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.