Использование Powershell для редактирования файла XML - PullRequest
1 голос
/ 22 апреля 2020

У меня есть файл XML, в котором мне нужно изменить строку подключения. Ниже приведен пример файла.

<policy>
  <application-policy name="Part1">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname:1521/test=</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part2">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname:1521/test=</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part3">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname:1521/test=</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part4">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname:1521/test</module-option>
      </login-module>
    </authentication>
  </application-policy>
</policy>

Как мне изменить строку "jdbc:oracle:thin:@hostname: 1521 / test", которая находится в пределах module-option в четырех местах.

Строка всегда одна и та же и будет заменена четыре раза из одной и той же переменной.

Ниже приведено то, что я пробовал, но оно только меняет собственно имя "dbUrl" и только первое время.

$xmlFile = "C:\Users\Dan\Desktop\login-Config.xml"
[xml]$doc = Get-Content $xmlFile
$node = $doc.SelectSingleNode("/policy/application-policy/authentication/login-module/module-option[@name='dbUrl']")
$node.name = "jdbc:oracle:thin:@hostname1:1521/test1"
$doc.Save($xmlFile)

Ниже я хотел бы, чтобы вывод выглядел так.

<policy>
  <application-policy name="Part1">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test=</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part2">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test=</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part3">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test=</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part4">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test</module-option>
      </login-module>
    </authentication>
  </application-policy>
</policy>

Ответы [ 3 ]

2 голосов
/ 22 апреля 2020

Используйте SelectNodes() вместо SelectSingleNode(), если вы хотите все из них, и убедитесь, что вы пишете в свойство InnerText вместо Name:

foreach($urlNode in $doc.SelectNodes("/policy/application-policy/authentication/login-module/module-option[@name='dbUrl']")){
  $urlNode.InnerText = "jdbc:oracle:thin:@hostname1:1521/test1"
}
1 голос
/ 22 апреля 2020

Вы можете сначала выполнить итерацию каждого узла <application-policy>, затем выполнить итерацию каждого узла <module-option> и установить только InnerText для новой строки соединения с name="dbUrl".

Демо:

# Create XML object from file
[xml]$xml = Get-Content -Path "test.xml"

# Iterate each policy node
foreach ($policy in $xml.policy.ChildNodes)
{
    # Iterate each module option node
    foreach ($moduleOption in $policy.authentication.'login-module'.'module-option')
    {
        # Only the dbUrl module option
        if ($moduleOption.name -eq "dbUrl")
        {
            $moduleOption.InnerText = "jdbc:oracle:thin:@hostname1:1521/test1/test"
        }
    }
}

# Save to output XML file
$xml.Save("output.xml")

выход. xml

<policy>
  <application-policy name="Part1">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part2">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part3">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test</module-option>
      </login-module>
    </authentication>
  </application-policy>
  <application-policy name="Part4">
    <authentication>
      <login-module code="jboss.loginmodule" flag="required">
        <module-option name="allowEmptyPasswords">false</module-option>
        <module-option name="dbUrl">jdbc:oracle:thin:@hostname1:1521/test1/test</module-option>
      </login-module>
    </authentication>
  </application-policy>
</policy>
0 голосов
/ 22 апреля 2020

Загрузите файл XML следующим образом $ do c = (g c $ configPath) -as [xml]

После сохранения xml в var .. теперь вы можете читать и заменять данные

   $doc.SelectSingleNode('//connectionStrings/add[@name="'+ $connectionName +'"]/@connectionString').'#text' = $connectionString

   $doc.Save($configPath)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...