参考Replace placeholders with actual values in PowerShell dictionary
我试图用实际元素值dynamically
替换PowerShell字典中的占位符。我从上面的帖子中得到了一个合适的答案,但这并没有多大帮助,因为它是一个静态的解决方案。需求经常变化,所以我不能在PowerShell脚本中硬编码。我对PowerShell脚本进行了一些更改并尝试运行。但是遇到了一些错误。以下是我的代码:
$xmldata = @"
<configuration>
<environment id="Development">
<type>Dev</type>
<client>Arizona%%type%%</client>
<dataSource>Local%%client%%</dataSource>
<path>App_Data\%%type%%\%%client%%_%%dataSource%%</path>
<targetmachines>
<targetmachine>
<name>Any</name>
<remotedirectory>D:\Inetpub\Test</remotedirectory>
</targetmachine>
</targetmachines>
</environment>
</configuration>
"@
[System.Xml.XmlDocument] $configxml = [xml]$xmldata
$environmentId = "Development"
$keyValuePairs = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]"
$configxml.SelectNodes("//configuration/environment[@id='$($environmentId)']//*[not(*)]") | `
ForEach-Object {
if($_.ParentNode.ToString() -ne "targetmachine")
{
$keyValuePairs.Add($_.Name, $_.InnerText)
}
}
Write-Output $keyValuePairs
Foreach ($key in $keyValuePairs.Keys)
{
$strings = [regex]::Matches($keyValuePairs[$key], '%%([^/)]+?)%%') |ForEach-Object { $_.Groups[1].Value }
$strings = $strings | sort -unique
if ($strings.Count -gt 0)
{
$finalValue = $keyValuePairs[$key]
$finalValue
foreach ($placeholder in $strings)
{
write-host "one of the place holder is" -ForegroundColor Green
$placeholder
#replacing all of the placeholders (which exists between %%---%%) with actual values
$finalValue = $finalValue.Replace("%%$placeholder%%",$keyValuePairs[$placeholder])
}
#Replace the original value with actual value
$keyValuePairs[$key] = $finalValue
}
}
Write-Output $keyValuePairs
尝试覆盖字典值时出现以下错误
Collection was modified; enumeration operation may not execute.
At line:33 char:10
+ Foreach ($key in $keyValuePairs.Keys)
+ ~~~~
+ CategoryInfo : OperationStopped: (:) [], InvalidOperationExcept
ion
+ FullyQualifiedErrorId : System.InvalidOperationException
注意:基本上我尝试使用动态方法替换字典值中的占位符。有人可以帮助我如何实现以下输出
Key Value
--- -----
type Dev
client ArizonaDev
dataSource LocalArizonaDev
path App_Data\Dev\ArizonaDev_LocalArizonaDev
答案 0 :(得分:0)
对于给定的xml
数据集,以下脚本应按预期工作。对于更复杂的嵌套占位符结构,请参阅### loop while ...
条评论(并考虑一下)。
$xmldata = @"
<configuration>
<environment id="Development">
<type>Dev</type>
<client>Arizona%%type%%</client>
<dataSource>Local%%client%%</dataSource>
<path>App_Data\%%type%%\%%client%%_%%dataSource%%</path>
<targetmachines>
<targetmachine>
<name>Any</name>
<remotedirectory>D:\Inetpub\Test</remotedirectory>
</targetmachine>
</targetmachines>
</environment>
</configuration>
"@
[System.Xml.XmlDocument] $configxml = [xml]$xmldata
$environmentId = "Development"
$keyValuePairs = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]"
$configxml.SelectNodes("//configuration/environment[@id='$($environmentId)']//*[not(*)]") | `
ForEach-Object {
if($_.ParentNode.ToString() -ne "targetmachine")
{
$keyValuePairs.Add($_.Name, $_.InnerText)
}
}
"BEFORE---->"
Write-Output $keyValuePairs | ft -AutoSize -Wrap
### loop while [Regex]::Matches($keyValuePairs.path,"%%(.+?)%%*") START
$aux = $($keyValuePairs.GetEnumerator())
for ($i=0; $i -lt $aux.Count; $i++) {
$auxKey = $aux[$i].Key
$auxVal = $aux[$i].Value
$m = [Regex]::Matches($keyValuePairs.path,"%%(.+?)%%*")
$m | % {
$tag = $_.Groups[1].Value
if ( $tag -match '%%') {
# wait until replaced
} else {
$keyValuePairs.$auxKey = $keyValuePairs.$auxKey -replace "%%$tag%%", $($keyValuePairs.$tag)
$aux = $($keyValuePairs.GetEnumerator()) # renew values after replace
}
}
}
### loop while [Regex]::Matches($keyValuePairs.path,"%%(.+?)%%*") END
"AFTER---->"
Write-Output $keyValuePairs | ft -AutoSize -Wrap
<强>输出强>:
PS D:\PShell> D:\PShell\SO\42687374.ps1
BEFORE---->
Key Value
--- -----
type Dev
client Arizona%%type%%
dataSource Local%%client%%
path App_Data\%%type%%\%%client%%_%%dataSource%%
AFTER---->
Key Value
--- -----
type Dev
client ArizonaDev
dataSource LocalArizonaDev
path App_Data\Dev\ArizonaDev_LocalArizonaDev
答案 1 :(得分:0)
=IF(F4>0, "Should Save", IF(F4<0, "Owed", ""))