No announcement yet.

Edit attributes in an XML with nsisXML by Wizou

  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Thanks again Anders.

    Ok, so I don't need the installer to create an xml file.
    The program itself will create settings.xml with all the default values - on first run on clean installs.

    I just need to check and adjust that one existing setting on upgrades.

    The following are already declared/defined in the main nsi script so aren't required for this section:

    Unicode True
    RequestExecutionLevel Admin
    !include "LogicLib.nsh"
    !define FILES_PATH

    Here's what I've got so far

    PHP Code:
    Section "name3"
    SetOutPath $INSTDIR\Bin
    "foo" "" "blah"

    ; If it existsbackup current component settings file first
    ${If} ${FileExists"$SETTINGSDIR\path\to\name3\settings.xml"
    CreateDirectory "$SETTINGSDIR\path\to\name3\backup"
    CopyFiles /SILENT "$SETTINGSDIR\path\to\name3\settings.xml" "$SETTINGSDIR\path\to\name3\backup\settings.xml"

    Force using new default service on upgrades
    ::load "$SETTINGSDIR\path\to\name3\settings.xml"
    ${If} $0 P<> 0
    ::select '/program/my'
    ${If} $1 P<> 0
    ::setAttribute "service" ""
    nsisXML::save "$SETTINGSDIR\path\to\name3\settings.xml"
    nsisXML::release $0
    nsisXML::release $1
    I've also tried the following variations:

    nsisXML::select '/program:settings/my'
    nsisXML::setAttribute "service" ""
    I've also tried adding your extra lines:

    System::Call 'KERNEL32::GetTickCount()i.r5' ; Get arbitrary value in $5
    nsisXML::setAttribute "url" "$5"

    Although I'm not sure what this does tbph.
    There can't be anything like /?id= after the service url.
    Was it just an example to show how an edit should work?

    The installer compiles and runs properly.

    The settings dir and file (in %AppData%) are not read-only.
    The folder has full write permissions etc.

    Everything works, except...when I go to the Settings folder,
    settings.xml has not been modified and the old custom value for <my service=""/> still exists.

    I'm not sure what I'm doing wrong.


    • #17
      I asked you to get my example working before doing anything else!

      If you wish to go on alone; after nsisXML::load, MessageBox $0. After nsisXML::select, MessageBox $1 or $2 or whatever the plug-in readme says it writes to.
      IntOp $PostCount $PostCount + 1


      • #18
        Sorry. I couldn't get it working.
        As I said, all that happened was a new settings.xml file was created.
        I've tried everything you've suggested so far.
        I've tried over and over again.

        With your modified version, it (rightly) skips the "prepare example" section if settings.xml exists - and if it doesn't exist, I don't need the installer to create a new xml file.

        I've read the plugin readme again and there's no ref to MessageBox or similar.

        It's driving me crazy :-(

        If only it was a simple .ini file instead.


        • #19
          I know there is no reference to MessageBox, you just need to use it to see the return values. I changed my example, try again.
          IntOp $PostCount $PostCount + 1


          • #20
            Thanks for your patience Anders

            This is what I get with the revised example:

            Program Installer

            0 should not be 0 here


            • #21
              nsisXML::select is failing to find the node.

              1) Delete the .xml and try again. Inspect the .xml, does the select path look valid?
              2) Compile my example and upload the .exe here in a .zip
              IntOp $PostCount $PostCount + 1


              • #22
                Sure, I can do that (2), but before I do...

                It works if I manually change the <program:settings xmlnsrogram="" version="3"> line to just <program>

                (and obviously also manually change the closing tag at the end to just </program>)

                The message is then "111135688 should not be 0 here"
                and the service url value is changed.

                However, the <program:settings xmlns:name="" version="3"> line exists on all installations, so we'd need to somehow change it and get the program itself to recognise the change ?

                We can't delete the existing xml file first because it can contain a ton of user data from over the years.

                For whatever reason (the colon, the xmlns, the extra params), possibly due to msxml, it's not finding the node.


                • #23
                  It would work if there was some way for the installer to rename
                  <program:settings xmlnsrogram="" version="3"> to just <program>

                  Then make the change to the "service" value.

                  Then rename the node back to the original name.

                  And all whilst keeping all the rest of the existing settings and data.

                  But something tells me that's not possible?


                  • #24
                    I wanted to get my example working first so we did not have to deal with too many issues at once.

                    I assume there is a way to deal with namespaces but I'm no XML expert. Maybe you could try reading a bit about MSXML on MSDN...

                    IntOp $PostCount $PostCount + 1


                    • #25
                      Thanks again Anders.
                      Yes, we'll need to do some research and rethink things.
                      I'll post here if I find a solution involving NSIS.


                      • #26
                        According to if you have
                        <e:Envelope xmlns:e=""> <e:Body><s:Search xmlns:s="">
                        the xpath expression is "/e:Envelope/e:Body/s:Search".

                        Notice xmlns:e, where your xml uses xmlns:name instead of xmlnsrogram or settings or whatever it is supposed to be.
                        IntOp $PostCount $PostCount + 1


                        • #27
                          So in my example:

                          <?xml version="1.0" encoding="UTF-16"?>
                          <program:settings xmlnsrogram="" version="3">
                          <settings setting1="whatever1" setting2="whatever2" setting3="whatever3"/>
                          <moresettings setting4="whatever4" setting5="whatever5" setting6="whatever6"/>
                          <my service=""/>
                          <data>loads more data here</data>

                          The xpath expression for service="" attrib is...?

                          "/program:settings/my" ?

                          I tried that with your script and got "0 should not be 0 here" :-(

                          Originally Posted by Anders View Post
                          According to if you have the xpath expression is "/e:Envelope/e:Body/s:Search".

                          Notice xmlns:e, where your xml uses xmlns:name instead of xmlnsrogram or settings or whatever it is supposed to be.
                          Yes, that was originally a mistake on my behalf (in this thread).
                          The two values are actually the same in the xml:

                          <program:settings xmlnsrogram=...