48

Please help me create a Powershell script that will go through an XML file and update content. In the example below, I want to use the script to pull out and change the file path in the Config.button.command example. Change C:\Prog\Laun.jar to C:\Prog32\folder\test.jar. Please help. Thanks.

<config>
 <button>
  <name>Spring</name>
  <command>
     C:\sy32\java.exe -jar "C:\Prog\Laun.jar" YAHOO.COM --type SPNG --port 80
  </command>
  <desc>studies</desc>
 </button>
 <button>
  <name>JET</name>
    <command>
       C:\sy32\java.exe -jar "C:\Prog\Laun.jar" YAHOO.COM --type JET --port 80
    </command>
  <desc>school</desc>
 </button>
</config>
1

3 Answers 3

70

I know this is an old post but this may help others so...

If you specifically know the elements that you are looking for then you can simply specify the element like so:

# Read the existing file
[xml]$xmlDoc = Get-Content $xmlFileName

# If it was one specific element you can just do like so:
$xmlDoc.config.button.command = "C:\Prog32\folder\test.jar"
# however this wont work since there are multiple elements

# Since there are multiple elements that need to be 
# changed use a foreach loop
foreach ($element in $xmlDoc.config.button)
{
    $element.command = "C:\Prog32\folder\test.jar"
}
    
# Then you can save that back to the xml file
$xmlDoc.Save("c:\savelocation.xml")
Sign up to request clarification or add additional context in comments.

1 Comment

@cdp that content now 404s, but seems available here: sorastog.blogspot.com/2014/05/…
50

You have two solutions. You could read it as xml and replace the text, like this:

#using xml

#get the content of this file and cast as an XML object, so we can parse it
$xml = [xml](Get-Content .\test.xml)

#find all nodes that match
$matchingNodes = $xml.SelectNodes("//command") 
foreach($node in $matchingNodes){
        #if the node exists, it will have a .#text value.  If it exists, then replace the first bit of text with the second
        $node."#text" = $node."#text".Replace("C:\Prog\Laun.jar", "C:\Prog32\folder\test.jar") 
}

#save the changes
$xml.Save("C:\Users\graimer\Desktop\test.xml")

Or you could do the same much simpler and faster using simple string-replacement like if it was a normal text-file. I would recommend this. Ex:

#using simple text replacement
$con = Get-Content .\test.xml
$con | % { $_.Replace("C:\Prog\Laun.jar", "C:\Prog32\folder\test.jar") } | Set-Content .\test.xml

1 Comment

Note that //"command" in $xml.SelectNotes is case sensitive, eg exactly how it's shown in the .xml file.
3

Try this:

$xmlFileName = "c:\so.xml"
$match = "C:\\Prog\\Laun\.jar"
$replace = "C:\Prog32\folder\test.jar"


# Create a XML document
[xml]$xmlDoc = New-Object system.Xml.XmlDocument

# Read the existing file
[xml]$xmlDoc = Get-Content $xmlFileName

$buttons = $xmlDoc.config.button
$buttons | % { 
    "Processing: " + $_.name + " : " + $_.command
    $_.command = $_.command -Replace $match, $replace
    "Now: " + $_.command
    }

"Complete, saving"
$xmlDoc.Save($xmlFileName)

2 Comments

Shouldn't you escape the . in $match too? Also, you can combine the create and read xml parts with a simple cast. :-)
Yes, you correct on the . match, thank you for pointing that out. I often separate my create and read as often I build the xml from scratch if the xml files doesn't exist. It is not the case in this instance, but it is a pattern I have become used to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.