2017-03-08 98 views
1

替換實際值的佔位符下面是示例XML文件:在PowerShell中詞典

<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%% 

但將元素轉換爲鍵值對後,我想用actualy值替換佔位符。換句話說,元件的「路徑」有3個佔位符,他們是

1. type 
2. client 
3. dataSource 

基本上佔位符是指開始的字符串和具有兩個百分比(%% XYZ %%)結束。所以,我需要用實際值替換佔位符之後,下面的輸出:

Key       Value 
-----      ----- 
type      Dev 
client      Arizona 
dataSource     Local 
path      App_Data\Dev\Arizona_Local 

能有人幫我,我怎麼能實現這一目標使用PowerShell。提前致謝。

+0

你有什麼麻煩?匹配和替換字符串,或更改字典對象中的值? –

+0

我遇到匹配和替換字符串的問題。 – mahesh

回答

1

通常,使用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 

注意,如果你想要的東西性質完全動態的,它可以通過一些其他的方式讓所有的佔位符,就像捕獲正則表達式完成,但是似乎沒有必要根據問題的陳述。

+0

謝謝你的回覆吉爾。上面提到的xml文件只是一個例子。我需要一些本質上完全動態的東西。 – mahesh

+0

已更新的答案...以及您的ToLower()調用。 –

+0

非常感謝Gill。它按預期工作。 – mahesh