Avatar billede blod_1 Nybegynder
25. maj 2009 - 10:37 Der er 17 kommentarer og
1 løsning

ASP ændre i XML

Mit XML er som dette

<namelist>
  <user>
    <alias>
      <name>Dood Allen</name>
      <uuid>dce83176-7214-4649-b284-ba344b71799b</uuid>
      <altName>tralala</altName>
      <simName>FurNation Purgatory</simName>
    </alias>
  </user>
</namelist>

Hvordan gør jeg når jeg skal ændre f.eks altName? Er der en funktion til at ændre med? eller er den eneste måde at slette den helt, og så oprette den igen?
Avatar billede softspot Forsker
25. maj 2009 - 11:10 #1
Du kan bruge MSXML2.DomDocument til at indlæse og manipulere din XML.

Noget i stil med (quick and dirty - uden fejlhåndtering!):

filnavn_på_xmldoc = "c:\fil.xml"
set xd = Server.CreateObject("MSXML2.DOMDocument")
xd.Load filnavn_på_xmldoc
xd.documentElement.selectSingleNode("/namelist/user/altName").nodeValue = "Ændret!"
Avatar billede blod_1 Nybegynder
25. maj 2009 - 11:18 #2
Ah, ja det der ser betydeligt mere simpelt ud end det jeg fandt om at slette og oprette osv, men hvor kan jeg sætte ind sådan så den kun gør det ved en bestemt? den xml jeg har har mange <user></user> skal jeg så først kigge igennem sådan så den finder hvor uuid og simName er rigtigt, og så sætte den til at ændre nodeValue der?
Avatar billede softspot Forsker
25. maj 2009 - 11:31 #3
Du kan via XPath ret præcist udvælge den node du vil ændre. XPath kan bruges til at teste på node-navne og node-atributter, samt xml-struktur.

Med udgangspunkt i mit eksempel fra tidligere kan du f.eks. ændre altName for Dood Allen således:

filnavn_på_xmldoc = "c:\fil.xml"
set xd = Server.CreateObject("MSXML2.DOMDocument")
xd.Load filnavn_på_xmldoc
xd.documentElement.selectSingleNode("/namelist/user/alias[name='Dood Allen']/altName").nodeValue = "Ændret!"

den samme teknik gør sig gældende hvis du vil checke på uuid eller simName. Hvis dine elementer har atributter, f.eks.

<alias name="Dood Allen">
...
</alias>

kan du benytte XPath-syntaksen:

xd.documentElement.selectSingleNode("/namelist/user/alias[@name='Dood Allen']/altName").nodeValue = "Ændret!"

altså i stedet for blot name='...', så foranstiller du name med et snabela, altså @name='...'.
Avatar billede blod_1 Nybegynder
25. maj 2009 - 11:54 #4
Så har jeg prøvet lidt, men kan ikke helt få den til at gøre som jeg vil have den til.

"This operation can not be performed with a Node of type ELEMENT."

<%
simID = Request.ServerVariables("HTTP_X-SecondLife-Region")
aviID = Request.ServerVariables("HTTP_X-SecondLife-Owner-Key")
aviNa = Request.ServerVariables("HTTP_X-SecondLife-Owner-Name")

simID = trim(left(simID, InStrRev(simID, "(")-1))

name = Replace(Server.HTMLEncode(request("name")), "'", "''")
mode = Replace(Server.HTMLEncode(request("mode")), "'", "''")
simID = Replace(Server.HTMLEncode(simID), "'", "''")


if aviID <> "" and simID <> "" and name <> "" then
    strFileName = "data_names.xml"

    filnavn_paa_xmldoc = Server.MapPath(strFileName)
    set xd = Server.CreateObject("MSXML2.DOMDocument")
    xd.Load filnavn_paa_xmldoc
    xd.documentElement.selectSingleNode("/namelist/user/alias[uuid='" & aviID & "']/altName").nodeValue = name

    response.write(name)
end if
%>

Og hvordan når den skal søge både på uuid, og simName på samme tid?
Avatar billede softspot Forsker
25. maj 2009 - 12:01 #5
Du kan evt. prøve med:

xd.documentElement.selectSingleNode("/namelist/user/alias[uuid='" & aviID & "' and simName='" & simID & "']/altName").innerText = name

eller måske blot .text i stedet for .innerText.
Avatar billede blod_1 Nybegynder
25. maj 2009 - 12:08 #6
Så røg fejl meddelelserne, men den finder tilsyneladende ikke det den leder efter.

.innerText siger den ikke kan bruges


if aviID <> "" and simID <> "" and name <> "" then
    strFileName = "data_names.xml"

    filnavn_paa_xmldoc = Server.MapPath(strFileName)
    set xd = Server.CreateObject("MSXML2.DOMDocument")
    xd.Load filnavn_paa_xmldoc
    xd.documentElement.selectSingleNode("/namelist/user/alias[uuid='" & aviID & "' and simName='" & simID & "']/altName").Text = name

    response.write("Debug: " & aviID & " / " & simID & " / " & name)
end if

Debug: dce83176-7214-4649-b284-ba344b71799b / FurNation Purgatory / Test
Avatar billede softspot Forsker
25. maj 2009 - 12:09 #7
Nå, jeg kan se at der givetvis ikke er nogen af de foreslåede egenskaber som kan bruges (innerText og text), så det kan evt. være fordi der opereres direkte på resultatet af selectSingleNode, at problemet opstår (selvom det burde fungere, hvis altName ikke indeholder andet end tekst). Alternativt må du oprette en textnode og udskifte den eksisterende childnode på altName med den nye. Noget i stil med:

set xn = xd.documentElement.selectSingleNode("/namelist/user/alias[uuid='" & aviID & "' and simName='" & simID & "']/altName")
xn.replaceChild xd.createTextNode(name), xn.firstChild
Avatar billede softspot Forsker
25. maj 2009 - 12:16 #8
Du kan evt. teste om der findes noget i kaldet til selectSingelNode, ved at undersøge om xn er nothing. Hvis den er nothing findes der naturligvis ikke noget :-)

set xn = xd.documentElement.selectSingleNode("/namelist/user/alias[uuid='" & aviID & "' and simName='" & simID & "']/altName")
if not xn is nothing then
  xn.replaceChild xd.createTextNode(name), xn.firstChild
else
  response.write "brugeren kunne ikke findes."
end if
Avatar billede blod_1 Nybegynder
25. maj 2009 - 12:22 #9
Fantastisk, det var endda svaret på noget jeg regnede med at jeg skulle bikse med senere, fordi hvis den ikke findes, så skal den oprettes. Så det er perfekt til det jeg skulle lave senere.

Men her er resultatet fra det:

brugeren blev fundet.
Debug: dce83176-7214-4649-b284-ba344b71799b / FurNation Purgatory / test


    strFileName = "data_names.xml"

    filnavn_paa_xmldoc = Server.MapPath(strFileName)
    set xd = Server.CreateObject("MSXML2.DOMDocument")
    xd.Load filnavn_paa_xmldoc

    set xn = xd.documentElement.selectSingleNode("/namelist/user/alias[uuid='" & aviID & "' and simName='" & simID & "']/altName")
    if not xn is nothing then
      response.write "brugeren blev fundet."
      xn.replaceChild xd.createTextNode(name), xn.firstChild
    else
      response.write "brugeren kunne ikke findes."
    end if

    response.write("Debug: " & aviID & " / " & simID & " / " & name)


Så det må være xn.replaceChild xd.createTextNode(name), xn.firstChild den ikke gør rigtigt? Kan bare intet finde om den på google, ellers leder jeg efter noget forkert?
Avatar billede softspot Forsker
25. maj 2009 - 12:33 #10
Hvis man antager at altName kan være tom (dvs. ikke have nogen efterkommere), så kunne du måske få mere succes med at tjekke om firstChild findes inden du forsøger at udskifte den. Jeg forestiller mig noget i stil med:

    if not xn is nothing then
      response.write "brugeren blev fundet."
      if not xn.firstChild is nothing then
        xn.replaceChild xd.createTextNode(name), xn.firstChild
      else
        xn.appendChild xd.createTextNode(name)
      end if
    else
      response.write "brugeren kunne ikke findes."
    end if
Avatar billede softspot Forsker
25. maj 2009 - 12:35 #11
Referencemanualen til MSXML, XMLDOM er beskrevet her (specifikt replaceChild-metoden, resten finder du på samme site :-)): http://msdn.microsoft.com/en-us/library/ms753687(VS.85).aspx
Avatar billede blod_1 Nybegynder
25. maj 2009 - 13:43 #12
Stadig samme resultat med at den finder brugeren. Men den ændrer det ikke, er det altName den forsøger at ændre i overhovedet?

Eller det må det være når den bliver defineret her "']/altName") ?
Avatar billede softspot Forsker
25. maj 2009 - 13:48 #13
Hvordan aflæser du om værdien er blevet ændret? Hvis du læser i XML-filen, så skal du i det mindste huske at kalde xd.Save(filnavn) for at gemme oveni den eksisterende XML-fil...
Avatar billede blod_1 Nybegynder
25. maj 2009 - 14:02 #14
dough!!! Var jo det jeg havde glemt.

Var mere opmærksom på hvordan den fandt hvad osv. og så glemte jeg alt om at gemme ændringerne i filen til sidst.

Nu virker det hele som det skal, og endda med svar på flere spørgsmål på samme tid.
Avatar billede softspot Forsker
25. maj 2009 - 14:07 #15
Jamen, så velbekomme da :-)
Avatar billede blod_1 Nybegynder
25. maj 2009 - 14:10 #16
Hvis nogle skulle falde over dette emne igen senere, så blev det færdige funktionelle resultat dette:

    filnavn = "data_names.xml"

    filnavn_paa_xmldoc = (Server.MapPath(filnavn))
    set xd = Server.CreateObject("MSXML2.DOMDocument")
    xd.Load filnavn_paa_xmldoc

    set xn = xd.documentElement.selectSingleNode("/namelist/user/alias[uuid='" & aviID & "' and simName='" & simID & "']/altName")
    if not xn is nothing then
        if not xn.firstChild is nothing then
            xn.replaceChild xd.createTextNode(name), xn.firstChild
        else
            xn.appendChild xd.createTextNode(name)
        end if
    else
        response.write "brugeren kunne ikke findes."
    end if

    xd.Save(Server.MapPath(filnavn))
Avatar billede softspot Forsker
25. maj 2009 - 14:13 #17
Tak for point :-)
Avatar billede blod_1 Nybegynder
25. maj 2009 - 14:15 #18
Tak for svar da :-D Som endda hjalp på flere funktioner på samme tid... Næste jeg så skal til at finde ud af er hvordan man sletter ting hehehehe, men tror lige jeg starter på den msdn side.
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester