用 PowerShell 字典中的实际值替换占位符
Replace placeholders with actual values in PowerShell dictionary
以下是示例 xml 文件:
<configuration>
<environment id="Development">
<type>Dev</type>
<client>Arizona</client>
<dataSource>Local</dataSource>
<path>App_Data\%%type%%\%%client%%_%%dataSource%%</path>
<targetmachines>
<targetmachine>
<name>Any</name>
<remotedirectory>D:\Inetpub\Test</remotedirectory>
</targetmachine>
</targetmachines>
</environment>
</configuration>
我正在尝试使用以下脚本将上述 xml 文件转换为 PowerShell 字典。
[System.Xml.XmlDocument] $configxml = Get-Content xmlfile
$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.ToLower(), $_.InnerText)
}
}
Write-Output $keyValuePairs
我得到以下输出,这是预期的。
Key Value
----- -----
type Dev
client Arizona
dataSource Local
path App_Data\%%type%%\%%client%%_%%dataSource%%
但是在将元素转换为键值对后,我想用实际值替换占位符。也就是说,元素"Path"有3个占位符,它们是
1. type
2. client
3. dataSource
占位符基本上是指以两个百分比 (%%xyz%%) 开头和结尾的字符串。因此,在用实际值替换占位符后,我需要以下输出:
Key Value
----- -----
type Dev
client Arizona
dataSource Local
path App_Data\Dev\Arizona_Local
有人可以帮助我如何使用 PowerShell 实现此目的。提前致谢。
一般来说,当使用 xml 或 csv 数据发布示例时,在这里使用字符串来表示数据而不是引用其他人没有的文件是有帮助的。
类似这样的东西可以用来实现你的结果。
$xmldata = @"
<configuration>
<environment id="Development">
<type>Dev</type>
<client>Arizona</client>
<dataSource>Local</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
# A static way...
#$keyValuePairs.path = $keyValuePairs.path -replace '%%type%%', $keyValuePairs.type
#$keyValuePairs.path = $keyValuePairs.path -replace '%%client%%', $keyValuePairs.client
#$keyValuePairs.path = $keyValuePairs.path -replace '%%datasource%%', $keyValuePairs.datasource
# Something more dynamic
$m = [Regex]::Matches($keyValuePairs.path,"%%(.+?)%%*")
$m | % {
$tag = $_.Groups[1].Value
$keyValuePairs.path = $keyValuePairs.path -replace "%%$tag%%", $($keyValuePairs.$tag)
}
"AFTER---->"
Write-Output $keyValuePairs
请注意,如果您想要本质上完全动态的东西,可以通过其他方法获取所有占位符来完成,例如带捕获的正则表达式,但根据问题陈述,这似乎是不必要的。
以下是示例 xml 文件:
<configuration>
<environment id="Development">
<type>Dev</type>
<client>Arizona</client>
<dataSource>Local</dataSource>
<path>App_Data\%%type%%\%%client%%_%%dataSource%%</path>
<targetmachines>
<targetmachine>
<name>Any</name>
<remotedirectory>D:\Inetpub\Test</remotedirectory>
</targetmachine>
</targetmachines>
</environment>
</configuration>
我正在尝试使用以下脚本将上述 xml 文件转换为 PowerShell 字典。
[System.Xml.XmlDocument] $configxml = Get-Content xmlfile
$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.ToLower(), $_.InnerText)
}
}
Write-Output $keyValuePairs
我得到以下输出,这是预期的。
Key Value
----- -----
type Dev
client Arizona
dataSource Local
path App_Data\%%type%%\%%client%%_%%dataSource%%
但是在将元素转换为键值对后,我想用实际值替换占位符。也就是说,元素"Path"有3个占位符,它们是
1. type
2. client
3. dataSource
占位符基本上是指以两个百分比 (%%xyz%%) 开头和结尾的字符串。因此,在用实际值替换占位符后,我需要以下输出:
Key Value
----- -----
type Dev
client Arizona
dataSource Local
path App_Data\Dev\Arizona_Local
有人可以帮助我如何使用 PowerShell 实现此目的。提前致谢。
一般来说,当使用 xml 或 csv 数据发布示例时,在这里使用字符串来表示数据而不是引用其他人没有的文件是有帮助的。
类似这样的东西可以用来实现你的结果。
$xmldata = @"
<configuration>
<environment id="Development">
<type>Dev</type>
<client>Arizona</client>
<dataSource>Local</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
# A static way...
#$keyValuePairs.path = $keyValuePairs.path -replace '%%type%%', $keyValuePairs.type
#$keyValuePairs.path = $keyValuePairs.path -replace '%%client%%', $keyValuePairs.client
#$keyValuePairs.path = $keyValuePairs.path -replace '%%datasource%%', $keyValuePairs.datasource
# Something more dynamic
$m = [Regex]::Matches($keyValuePairs.path,"%%(.+?)%%*")
$m | % {
$tag = $_.Groups[1].Value
$keyValuePairs.path = $keyValuePairs.path -replace "%%$tag%%", $($keyValuePairs.$tag)
}
"AFTER---->"
Write-Output $keyValuePairs
请注意,如果您想要本质上完全动态的东西,可以通过其他方法获取所有占位符来完成,例如带捕获的正则表达式,但根据问题陈述,这似乎是不必要的。