0

I have an app that has a config file in XML format. I have created a powershell script that allows users to select from multiple configuration changes without manually editing the config. It works great for single elements. For example, if you choose "Config 1" below it works exactly as expected. It finds any matching elements, like fruit and replaces that line. Great. However, if a config element has child elements, it strips out the XML and puts it all as one value. For example, if you select "Config 2" below it would write this:

<fruit>banana</fruit>
<drink>tea</drink>
<dishes>forkbowl</dishes>

How can I fix this?

Here is Configurations.xml

<EnvironmentData>
  <demo friendlyName="Config 1">
    <fruit>apple</fruit>
    <drink>Soda</drink>
  </demo>
  <demo friendlyName="Config 2">
    <fruit>banana</fruit>
    <drink>tea</drink>
      <dishes>
        <utensil>fork</utensil>
        <dish>bowl</dish>
      </dishes>
  </demo>
</EnvironmentData>

Here is the code:

#load data into hash
$envVariableHash = @{}
$test = $envs.SelectNodes("//$envName")[0]
ForEach ($ele in $test.ChildNodes) {
    #Write-Host "$($ele.LocalName): $($ele.InnerText)"
    $envVariableHash.add($ele.LocalName, $ele.InnerText)
}

#read build config and replace matches
$buildConfigFile = [System.Xml.XmlDocument](Get-Content "$($config.localbuildspath)/$($buildName)/config.xml");
$buildConfig = $buildConfigFile.ConfigData;

ForEach ($ele in $buildConfig.ChildNodes) {
    if ($envVariableHash.ContainsKey($ele.LocalName)) {
        $ele.InnerText = $envVariableHash[$ele.LocalName]
        if ($isDev) { Write-Host "Updated $($ele.LocalName)" -ForegroundColor DarkGray }
    }
}
Write-Host "Saving File... " -NoNewline -ForegroundColor DarkGray
$buildConfigFile.Save("$($config.localbuildspath)/$($buildName)/config.xml")
Write-Host "Done" -ForegroundColor DarkGray

1 Answer 1

2

You are using .InnerText to get the content of a node. But .InnerText only returns the values of its nodes. Use .InnerXml instead:

  1. Change line 6 from $envVariableHash.add($ele.LocalName, $ele.InnerText) to $envVariableHash.add($ele.LocalName, $ele.InnerXml).
  2. Change line 15 from $ele.InnerText = ... to $ele.InnerXml = ....
Sign up to request clarification or add additional context in comments.

1 Comment

Fantastic. I hoped it was something silly/simple.

Your Answer

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