0

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.

2 Answers 2

2

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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)

2 Comments

I only tested the first one, but with these changes: ''' $xml.DocumentElement.ChildNodes | Where-Object { $_.name -eq 'access.key' } | ForEach-Object { $_.value = '{{ access_key }}' } '''
I ended up using this version, but both answers are correct

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.