Skip to content
⌘ NSIS Forum Archive

Is it possible to Edit and adjust an XML file through NSIS scripts or add-ons?

6 posts

swinster#

Is it possible to Edit and adjust an XML file through NSIS scripts or add-ons?

Hi All,

During an installation, I need to check for the existence of an XML file. If it isn't there I can copy across my own XML file, which is the easy part. However, if it exists I need to read through the nodes and either add a new node, or a adjust an existing node as necessary.

For example, lets assume this is the original XML file:


<MyApp>
<UserStuff name="Entry1">
.
.
</UserStuff >
<UserStuff name="Entry2">
.
.

</UserStuff >
</MyApp>
Now, the installer will always need to add the following XML for Entry3


<MyApp>
<UserStuff name="Entry3">
.
.
</UserStuff >
</MyApp>
If this node (Entry3) does NOT exist, then it will need to be added. However if the node already exists in the original XML file, the original node will need to be replaced with the new version.

I have looked over Wizou's nsisXML 1.4, and I can see that you can open a single XML file and select a node, but I will also need to open a second XML file, check to see if a node exists, then copy the saved node into the second file if it doesn't exist, or replace the node entirely.

I can't see a simple way to open multiple XML files and somehow copy nodes between them, or even to a temporary variable.

I hope this makes sense. If anyone has managed this I would for sure like to understand how it can be achieved.


From above, here is a summary of what I need to do:
1) If the Myapp.xml exists then Open it and check to see if the node "Entry3" exists
2) If the "Entry3" node doesn't exist, then copy the "Entry3" node from the second saved XML file to the Myapp.xml file
3) if "Entry3" node does exist, then modify/replace the node so that it is updated with the info in the saved XML (probably simpler to delete and re-add the node)
JasonFriday13#
There's a few XML plugins on the wiki: http://nsis.sourceforge.net/Category:Plugins.
swinster#
Thanks Jason,

I should have been more explicit. Indeed Wizou's nsisXML 1.4 can from the Wiki, but I couldn't figure out how to do what was needed. I did look at the the others, but couldn't figure them out either.


I will take another look, but was firstly interested to know if this was actually possible.
Anders#
Why not just ExecWait your application and have it do the merging? I'm assuming it can already read and write XML...
swinster#
Hi Anders,

My application does no reading/writing of XML, in fact the NSIS installer for me is all about simply putting the right files (scripts etc),other third party applications, and other small configuration tweaks onto the users machine.

What I'm attempting to do is update an XML configuration of a completely separate application that is used in by my scripts. 9/10 users do not use this particular part of the configuration so that XML file doesn't even exist, which is great for the first installation. Problem is, as I want to extend my little bit of config for this XML, an upgrade now has to deal with the file I added previously, but (of course), the user may well add their own config into this file, which I don't want to destroy and overwrite.

I trust this bit of background helps you understand what and why I'm attempting to do.
swinster#
After leaving this for some time, I finally had some spare time over the pas t couple of days. I couldn't seem to get this working in NSIS, but have come up with the following little PS Script that can be invoked using the http://nsis.sourceforge.net/PowerShell_support Plugin.This might not be the greatest code, but it seems to work.

I would have to extract the bundled Mylang.xml file to a know location so that the script can read it in.


# Setup the import the XML files
# userDefineLang.xml is the default Notepad++ XML file
$userDefineLangFile = "$env:APPDATA\Notepad++\userDefineLang.xml"
$userDefineLangXML = New-Object -TypeName XML

# Basic Test to ensure that the inport is ok
try {
$userDefineLangXML.Load($userDefineLangFile)
}
catch {
Write-Output "Import failed of Notepad++ User Defined Language XML file"
Exit 0
}

# MyLang.xml is the pre-made UDL for the My logs
$MyDefineLangFile = "C:\Tools\Scripts\MyLang.xml"
$MyDefineLangXML = New-Object -TypeName XML

# Basic Test to ensure that the inport is ok
try {
$MyDefineLangXML.Load($MyDefineLangFile)
}
catch {
Write-Output "Import failed of My Language XML file"
Exit 0
}

# Now read/filter the XML files to ensure the relevant node exists
$userLangXMLitem = Select-Xml -Xml $userDefineLangXML -XPath '//UserLang[@name="My"]'
$MyLangXMLitem = Select-Xml -Xml $MyDefineLangXML -XPath '//UserLang[@name="My"]'

# Test to see if the nodes slected above contian infoamtion
if (-not ($userLangXMLitem -eq $null)) {
if (-not ($MyLangXMLitem -eq $null)) {
# assuming both nodes do exist, then deleted the old My Lang nodes
$null = $userLangXMLitem.Node.ParentNode.RemoveChild($userLangXMLitem.node)
# then copy across the pre-built node
$userDefineLangXML.DocumentElement.PrependChild($userDefineLangXML.ImportNode($MyLangXMLitem.Node, $true))
# and save
$userDefineLangXML.Save($userDefineLangFile)
}
else {
Write-Output "Something has gone wrong, can't proceess User Defined Language files. No changes have been made to the Notepad++ UDL XML file."
}
}
elseif (-not ($MyLangXMLitem -eq $null)) {
# assuming the My node does not exist in the main UDL file, then just copy across the pre-0built node
$userDefineLangXML.DocumentElement.PrependChild($userDefineLangXML.ImportNode($MyLangXMLitem.Node, $true))
# and save
$userDefineLangXML.Save($userDefineLangFile)
}
else {
Write-Output "Something has gone wrong, can't proceess User Defined Language files. No changes have been made to the Notepad++ UDL XML file."
}