![]() |
#1 |
Junior Member
Join Date: Nov 2021
Posts: 8
|
Edit attributes in an XML with nsisXML by Wizou
I can't figure it out.
I try to modify an XML, but I get lost when finding the issue why it's not working. I have a file "foo.xml" HTML Code:
<global> <colors lava="orange" sky="blue" > </colors> </global> HTML Code:
<global> <colors lava="orange" sky="cyan" earth="brown" > </colors> </global> This is how my NSIS code looks like: code: I haven't found any information in the documentation how to overwrite, add, or remove attributes with their values. Do I have to remove entire nodes, and append them again in the end? |
![]() |
![]() |
![]() |
#2 |
Junior Member
Join Date: Nov 2021
Posts: 8
|
I think nsisXML by Joel will be the easier solution to my problem.
code: The simpliest way would be just to add the attributes, and hoping the old ones will be overwritten. But knowing life, I probably have to check the attribute to see if it exists, then eventually remove it, and then add new attributes: (Check if "sky" and "earth" exist, if they exist - remove them, create new attributes "sky" and "earth" with new values) |
![]() |
![]() |
![]() |
#3 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
The Wizou plugin uses MSXML and MSDN says: "Sets or updates the supplied attribute node on this element"
IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#4 |
Junior Member
Join Date: Nov 2021
Posts: 8
|
I got it.
This in nsisXML by Wizou should be written in an other way, so it would work. code: But it didn't work for me. But this below did work, in nsisXML by Joel. Last time updated in 2009. code: I didn't have to remove anything. There are no clones of attributes, it just works, and looks simple. If you have any ideas how the Wizous code should look like, please post your example. |
![]() |
![]() |
![]() |
#5 | |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
Quote:
PHP Code:
IntOp $PostCount $PostCount + 1 |
|
![]() |
![]() |
![]() |
#6 |
Junior Member
Join Date: Nov 2021
Posts: 8
|
Ah, yes. I forgot to save the file properly.
nsisXML::save requires an argument. The downside of the two nsisXML versions is, that the structure is being rebuilt. This is the result I was trying to achieve: HTML Code:
<global> <colors lava="orange" sky="cyan" earth="brown" > </colors> </global> HTML Code:
<global> <colors lava="orange" sky="cyan" earth="brown"> </colors> </global> |
![]() |
![]() |
![]() |
#7 | |
Junior Member
Join Date: Nov 2021
Posts: 8
|
Quote:
|
|
![]() |
![]() |
![]() |
#8 | |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
Quote:
PHP Code:
IntOp $PostCount $PostCount + 1 |
|
![]() |
![]() |
![]() |
#9 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
Hi
I've got a similar issue, so hope this is the right place to post it? I'm trying to edit one setting in an existing settings.xml file, on upgrades. This is what the settings file looks like (for sake of anonymity, values obviously aren't literal): code: I want the installer to change one setting as follows: code: It should be simple? I've put Wizou's unicode nsisXML.dll in NSIS\Unicode\Plugins\x86-unicode Section in installer.nsi PHP Code:
Any help would be greatly appreciated. Thanks! |
![]() |
![]() |
![]() |
#10 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
I've tried loads of different things from this thread and from the given example files, but the installer always crashes (with no errors).
Does nsisXML not work with UTF-16? Or is it something to do with the structure or chars in the node names & attribs (colons, http://, slashes, quotes, spaces)? Or is just that the syntax has to be exact - but mine is always wrong? Anyone? |
![]() |
![]() |
![]() |
#11 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
Check if $0 is 0 after nsisXML::load. If it is, it failed to load the XML file.
PHP Code:
IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#12 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
Wow, thank you very much Anders.
We're getting somewhere now. It compiles and doesn't crash. However, it's effectively creating a <1kb default settings file - which can also be achieved by just deleting settings.xml So it looks like just the "Prepare example" section is working, but nothing is happening for the nsisXML section. What I also didn't mention is there's a whole heap more user settings and data in the file which needs to be kept on upgrades. But that's why I was creating a backup, so at least nothing is lost. I'm also slightly embarrassed about getting the node/attrib/value wrong in my original script, but I know now. So again, thank you very much. I'll keep tinkering with it and will let you know how it goes. |
![]() |
![]() |
![]() |
#13 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
Are you sure you copied the DLL from the binU directory in the .zip? My code works for me, it changes mysite.com/service1/ to mynewsite.com/service2/...
IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#14 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
Oh, I think I see what's happening now.
You'll probably hate me for this, but I didn't realise we'd need to write a new temp transitional xml file first. I thought we could just directly edit the existing settings.xml file. The truth of the matter is that "http://mysite.com/service1/" is actually a random variable. It's a user override setting which could be any url. I want to change it to my new service url - or even just change it to empty, e.g. <my service=""/> The user can then decide if they want to keep the new service or manually override it again with their own custom url. So I've no way of knowing what the exact custom user url will be. Can we specify a wildcard? Or is there a way to get that exact value first with nsisXML::getAttribute? Though I have actually tried setting it to the same custom url in both settings.xml and the FileWriteUTF16LE $0 line, but it still doesn't work. I just get a new settings.xml file - so I'm obviously still doing something wrong. And yes, I can confirm that binU \ nsisXML.dll is definitely in the "NSIS\Plugins\x86-unicode" folder. _____________________________________ Also, in this line: <program><settings dontcare="" /><my service="http://mysite.com/service1/"/></program> Which "settings" is it referring to from my sample above? Is it this "settings"? <program:settings xmlns:name="http://mysite.com" version="3"> Or this "settings"? <settings setting1="whatever1" setting2="whatever2" setting3="whatever3"/> The reason being that those aren't the actual names, so I need to adapt it to my script accordingly. Sorry for the confusion. I really appreciate all the help! |
![]() |
![]() |
![]() |
#15 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
You can edit a existing xml file directly. I changed my example a bit to reflect this. Until you can get my example to work correctly we can't really move on. By correctly I mean, you can edit the <settings dontcare="xyz"/> part in Notepad and those changes should remain if you run the code again (but you will get a new url part after "?something=" every time you run it).
You can probably read the value but my example does not care what the value is, it just uses the attribute name ("service" in the "my" node). I was referring to <settings setting1="whatever1" setting2="whatever2" setting3="whatever3"/> but its name does not matter, I just slightly shortened your file. IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#16 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
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: code: Here's what I've got so far PHP Code:
code: code: I've also tried adding your extra lines: code: 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 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
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 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
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 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
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 | |
Junior Member
Join Date: Jul 2022
Posts: 11
|
Thanks for your patience Anders
This is what I get with the revised example: Quote:
|
|
![]() |
![]() |
![]() |
#21 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
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 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
Sure, I can do that (2), but before I do...
It works if I manually change the <program:settings xmlns:program="http://mysite.com" 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="http://mysite.com" 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 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
It would work if there was some way for the installer to rename
<program:settings xmlns:program="http://mysite.com" 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 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
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... https://docs.microsoft.com/en-us/pre...763742(v=vs.85) https://docs.microsoft.com/en-us/pre...754539(v=vs.85) IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#25 |
Junior Member
Join Date: Jul 2022
Posts: 11
|
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 | |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,505
|
According to https://docs.microsoft.com/en-us/dot...ace-navigation if you have
Quote:
Notice xmlns:e, where your xml uses xmlns:name instead of xmlns:program or settings or whatever it is supposed to be. IntOp $PostCount $PostCount + 1 |
|
![]() |
![]() |
![]() |
#27 | |
Junior Member
Join Date: Jul 2022
Posts: 11
|
So in my example:
code: The xpath expression for service="" attrib is...? "/program:settings/my" ? I tried that with your script and got "0 should not be 0 here" :-( Quote:
The two values are actually the same in the xml: <program:settings xmlns:program=... |
|
![]() |
![]() |
![]() |
|
Tags |
attribute, joel, wizou, xml |
Thread Tools | Search this Thread |
Display Modes | |
|
|