2017-03-08 5 views
1

に実際の値を持つプレースホルダを交換後は、サンプルXMLファイルです:私は次のスクリプトを使用してPowerShellの辞書に上記の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> 

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

しかし、要素をキー値のペアに変換した後、プレースホルダを実際の値に置き換えたいとします。換言すれば、要素「パス」は3つのプレースホルダを有し、それらは基本的に、プレースホルダ

1. type 
2. client 
3. dataSource 

あり始まり二パーセント(%% XYZ %%)で終わる文字列を意味します。だから、私は実際の値でプレースホルダを交換した後、次の出力が必要になります。

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

誰かが、私はPowerShellを使用して、これをachiveすることができますどのように私を助けてください。前もって感謝します。

+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

ありがとう、ギル。それは期待どおりに働いています。 – mahesh