Проблемы с записью вложенных XML-элементов в PowerShell

У меня есть приложение с файлом конфигурации в формате XML. Я создал сценарий powershell, который позволяет пользователям выбирать из нескольких изменений конфигурации без ручного редактирования конфигурации. Он отлично работает для отдельных элементов. Например, если вы выберете Config 1 ниже, он будет работать точно так, как ожидалось. Он находит все совпадающие элементы, такие как fruit, и заменяет эту строку. Большой. Однако, если у элемента конфигурации есть дочерние элементы, он удаляет XML и помещает все это как одно значение. Например, если вы выберете Config 2 ниже, будет написано следующее:

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

Как я могу это исправить?

Вот 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>

Вот код:

#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

person JOATMON    schedule 06.05.2021    source источник


Ответы (1)


Вы используете .InnerText для получения содержимого узла. Но .InnerText возвращает только значения своих узлов. Используйте .InnerXml. вместо:

  1. Измените строку 6 с $envVariableHash.add($ele.LocalName, $ele.InnerText) на $envVariableHash.add($ele.LocalName, $ele.InnerXml).
  2. Измените строку 15 с $ele.InnerText = ... на $ele.InnerXml = ....
person stackprotector    schedule 06.05.2021
comment
Фантастика. Я надеялся, что это что-то глупое/простое. - person JOATMON; 06.05.2021