Home > OS >  Powershell XML replace element with new value
Powershell XML replace element with new value

Time:12-06

I have an xml file with a number of properties

 <configuration>
  <property>
    <name>access.key</name>
    <value>fred</value>
  </property>
  <property>
    <name>access.secret</name>
    <value>blog</value>
  </property>
</configuration>

I want to replace the property value based on the property name. I've tried a number of ways. I'm having issues because name and value are elements of property and not attributes. I had though this would work but no luck.

    $file = "site.xml"
    $xml = New-Object XML
    $xml.Load($file)
    $nodes = $xml.SelectNodes('/configuration/property') 
    foreach ($node in $nodes) {
      $property = $node.Attributes.GetNamedItem("name").Value
      if ($property -eq 'access.key')
        {
          $node.Attributes.SetNamedItem("value").Value = '{{ access_key }}'
        }
    }

    $xml.Save($file)

The following changed, but it changed value of name which makes sense because I selected the SingleNode property name. How do I change the property value base on the name?

     $node =  $xml.SelectSingleNode("/configuration/property/name[.= 'access.key']")
     $node.innerText = '{{ access_key }}'

It seems simple and probably is, hope someone can shed some light.

CodePudding user response:

I used the contents of the .xml you included to do a test and I think the below script will do what you're looking for.

I removed the $property variables and just changed the If statement to require the $node.name to be equal to the name you're looking for. If it is, then it will update $node.value and save the .xml after it finishes the ForEach loop:

$file = "site.xml"
$xml = New-Object XML
$xml.Load($file)
$nodes = $xml.SelectNodes('/configuration/property') 
foreach ($node in $nodes) {
  if ($node.name -eq 'access.key')
    {
        $node.Value = '{{ access_key }}'
    }
}

$xml.Save($file)

CodePudding user response:

There's various ways of doing this:

$fileName = 'D:\Test\site.xml'

$xml = New-Object -TypeName 'System.Xml.XmlDocument'
$xml.Load($fileName)

$xml.DocumentElement.ChildNodes | Where-Object { $_.name -eq 'access.key' } | ForEach-Object { $_.name = 'access_key' }
# or
# $xml.configuration.property | Where-Object { $_.name -eq 'access.key' } | ForEach-Object { $_.name = 'access_key' }
# or
# $xml.SelectNodes("//property/name[text() = 'access.key']") | ForEach-Object { $_.innerText = 'access_key' }

$xml.Save($fileName)
  • Related