在Powershell中在运行时合并JSON对象

时间:2016-02-23 06:08:44

标签: json powershell

昨天提出问题(JSON and references to other JSON objects)。

是否有可能以类似的方式在运行时合并JSON对象?

在我的test.json中,我希望在运行时将$ Defaults.wimos对象插入到WIMS.wimos中,类似于我在$ Defaults中对$ Paths.drive值所做的操作。

{
    Paths: {drive: "W:"},
    Defaults: {wimos: {dstdrive: "$($Paths.drive)"}
    },
    WIMS: {
        winos: "$($Defaults.wimos)",
        wimre: {dstdrive: "$($Paths.drive)"}
    }
}

在下面的代码中,我无法确定在运行时替换对象的语法。

$JSONConfig="test.json"
$rawJSON = (Get-Content $JSONConfig -Raw)
$pathJSON = $rawJSON | ConvertFrom-Json
#
# Load Paths from JSON into $Paths
#
$Paths=$pathJSON.Paths 
#
# Merge JSON objects to have the defaults replaced  
#
$DefaultsJSON=($ExecutionContext.InvokeCommand.ExpandString($rawJSON)) | ConvertFrom-Json
#
# Load Defaults into $Defaults
#
$Defaults=$DefaultsJSON.Defaults
#
# Merge JSON objects to have the System replaced  
#
$JSON = ($ExecutionContext.InvokeCommand.ExpandString($rawJSON)) | ConvertFrom-Json

$JSON.WIMS
write-host ("JSON.WIMS.wimre.dstdrive =" + $JSON.WIMS.wimre.dstdrive)
write-host ("JSON.WIMS.wimos.dstdrive =" + $JSON.WIMS.wimos.dstdrive)   #This fails to access and print "W:"

我希望能够替换$($ Defaults.wimos)并能够查询dstdrive成员。

这有可能在PowerShell中实现吗?有关如何的任何建议?

由于

斯图尔特

2 个答案:

答案 0 :(得分:0)

您的脚本失败的原因是由于$Defaults.wimos不是字符串{ dstdrive: "W:" }而是PSCustomObject,它将被内插到值@{drive=W:}。要获得正确的行为,您需要将$Defaults.wimos值转换回json字符串。

$Defaults = $DefaultsJSON.Defaults
$Defaults.wimos = $Defaults.wimos | ConvertTo-Json -Compress

答案 1 :(得分:0)

您的代码中存在一些问题。首先,插入到模板中的值将被插值为字符串而不是json对象。

为此,您可以在模板中使用ConvertTo-json。我会在一分钟内告诉你。

如果您要重新创建并使用不同的"模板"在同一个文件中(如路径,默认值等),我会创建一个辅助函数,用于在会话变量上一直重新创建/填充模板(以避免重复代码)。

创建以下方法:

function Get-ParsedJsonTemplate(){
   return ($ExecutionContext.InvokeCommand.ExpandString((Get-Content $JSONConfig -Raw))) | ConvertFrom-Json
} 

将模板json更改为以下内容(显示您可以在模板文件中使用powershell代码:

{
 Paths: {drive: "W:"},
 Defaults: {wimos: {dstdrive: "$($Paths.drive)"}},
 WIMS: {
    winos: $(
        if($Defaults -and $Defaults.wimos){
            $Defaults.wimos|ConvertTo-Json -Compress
        } else {
            @{"dstdrive"=""}|ConvertTo-Json -compress
        }
    ),
    wimre: {dstdrive: "$($Paths.drive)"}
 }
}

您的模板或打印输出中也有拼写错误(我看到您在"打印输出"在powershell中使用了wimos,在模板中使用了#34; winos"我修改了代码和以下内容应该适合您(给定上面的test.json):

$JSONConfig="c:\tmp\test.json"

function Get-ParsedJsonTemplate(){
    return ($ExecutionContext.InvokeCommand.ExpandString((Get-Content $JSONConfig -Raw))) | ConvertFrom-Json
}

$pathJSON = Get-ParsedJsonTemplate;
$Paths=$pathJSON.Paths 
$DefaultsJSON=Get-ParsedJsonTemplate;
$Defaults=$DefaultsJSON.Defaults
$JSON = Get-ParsedJsonTemplate;
$JSON.WIMS
write-host ("JSON.WIMS.wimre.dstdrive =" + $JSON.WIMS.wimre.dstdrive)
write-host ("JSON.WIMS.wimos.dstdrive =" + $JSON.WIMS.winos.dstdrive)