Powershell在XML中使用重复行查找和替换

时间:2020-06-02 11:19:19

标签: xml powershell

目标:

我希望Powershell脚本能够查找和替换singel XML文件中的文本。但是我只想更改XML中的参数之一。 (请参见下面的XML)

类似的东西

(Get-Content C:\test\config.xml).Replace("<Comport>1", "<Comport>2") | Set-Content C:\test\config.xml

经过一天的谷歌搜索和阅读Stackoverflow之后,我仍然无法弄清楚它。

问题:

xml文件确实包含许多相同的单词和句子。

XML文件不会总是包含相同数量的数据或行。

我不知道如何定位包含“ comport”的右行。

摘录自XML:

<Config>
  <utiliti1>
    <Enabled>1</Enabled>
    <Comport>0</Comport>
    <Baudrate>9600</Baudrate>
    <Stopbit>1</Stopbit>
    <Parity>NONE</Parity>
    <Databits>8</Databits>
    <IpPort>0</IpPort>
    <IpAdresse>0</IpAdresse>
  </utiliti1>
  <utiliti2>
    <Enabled>1</Enabled>
    <Comport>0</Comport>
    <Baudrate>9600</Baudrate>
    <Stopbit>1</Stopbit>
    <Parity>NONE</Parity>
    <Databits>8</Databits>
    <IpPort>0</IpPort>
    <IpAdresse>0</IpAdresse>
  </utiliti2>
  <utiliti3>
    <Enabled>1</Enabled>
    <Comport>0</Comport>
    <Baudrate>9600</Baudrate>
    <Stopbit>1</Stopbit>
    <Parity>NONE</Parity>
    <Databits>8</Databits>
    <IpPort>0</IpPort>
    <IpAdresse>0</IpAdresse>
  </utiliti3>

1 个答案:

答案 0 :(得分:0)

如果您不知道要选择哪个utiliti*节点,但知道唯一的comport值,则可以执行以下操作:

# Find and replace Comport 20 with 37
$x = [xml](Get-Content C:\test\config.xml)
$x.SelectSingleNode('//Config/*[Comport="20"]').Comport = '37'
$x.Save('C:\test\config.xml')

XPATH //Config/*[Comport="20"]选择带有子元素的Config元素,该子元素包含一个名为Comport且字符串值为20的子元素。


如果您想用新值替换未知数量的重复Comport值,则可以执行以下操作:

$x = [xml](Get-Content C:\test\config.xml)
$usedComports = @{} # Tracks already seen comports
$newComport = 0 # Current available comport 
$comportNodes = $x.SelectNodes('//Config/*[Comport]')
$comports = $comportNodes.Comport
($comportNodes | Group Comport | Where Count -gt 1).Group | Foreach-Object {
    if ($_.Comport -in $usedComports.Keys) {
        # Increase $newComport until it is unique among your xml comport values
        do {$newComport++} until ($newComport -notin $comports+$usedComports.Keys)
        $_.Comport = "$newComport" # Using quotes to make it a string
    }
    # Adds current comport to tracker table
    if ($_.Comport -notin $usedComports.Keys) {
        $usedComports.Add($_.Comport,0)
    }
}
$x.Save('C:\test\config.xml')