默认情况下,PowerShell的ConvertFrom-Json
cmdlet似乎不处理JSON文档中的引用。
{
"foo": {"$ref": "#/bar"},
"bar": true
}
我真的不知道这个JSON规范的官方状态(请参阅here和here),但有没有办法在PowerShell中管理这样的事情?
答案 0 :(得分:1)
AFAIK没有内置的方法来解析JSON引用。我经常搜索一个C#解决方案来解决PowerShell不支持的问题,因为大多数时候这些问题都可以转换为PowerShell代码,但是我无法在C#中找到一种简单的方法来做到这一点。自定义代码。
所以我认为您可能需要自己编写一些函数并使用类似Invoke-Expression
和引用类型(转换后的对象就像它是PSCustomObject)来帮助您。
概念证明(包含许多错误):
$json = @'
{
"foo": {"$ref": "#/bar"},
"bar": true
}
'@
$t = ConvertFrom-Json -InputObject $json
Write-Host "Before"
$t | Out-Host
function resolveReferences ($obj) {
#Loop through propeties
$obj.psobject.Properties | ForEach-Object {
#ref-values are PSCustomObjects with a $ref-property, so let's find the PSCustomObjects
if ($_.TypeNameOfValue -eq 'System.Management.Automation.PSCustomObject') {
#Verify it was a ref-value by checking for $ref-property
if ($_.Value.'$ref') {
#Convert value to powershell-path like $t.foo
$refpath = $_.Value.'$ref'.Replace("#/",'$t.').Replace("/",".")
#Execute generated powershell-path to get the referenced object and replace reference with the referenced object
$_.Value = (Invoke-Expression -Command $refpath)
}
}
}
}
resolveReferences -obj $t
Write-host "After"
$t | Out-Host
输出:
Before
foo bar
--- ---
@{$ref=#/bar} True
After
foo bar
--- ---
True True
您可以扩展以满足您的需求。防爆。支持对象数组:
$json = @'
{
"foo": {"$ref": "#/bar"},
"fooarray": [
{"item": {"$ref": "#/bar"}},
{"item": {"$ref": "#/hello"}}
],
"test": [1,2,3],
"bar": true,
"hello": "world"
}
'@
$t = ConvertFrom-Json -InputObject $json
Write-Host "Before"
$t | Out-Host
function resolveReferences ($obj) {
$obj.psobject.Properties | ForEach-Object {
if ($_.TypeNameOfValue -eq 'System.Management.Automation.PSCustomObject') {
if ($_.Value.'$ref') {
$refpath = $_.Value.'$ref'.Replace("#/",'$t.').Replace("/",".")
$_.Value = (Invoke-Expression -Command $refpath)
}
} elseif ($_.TypeNameOfValue -eq 'System.Object[]') {
#If array, loop through objects (recursive search)
$_.Value | ForEach-Object { resolveReferences -obj $_ }
}
}
}
resolveReferences -obj $t
Write-host "After"
$t | Out-Host
输出:
#item properties in fooarray-objects are ref paths, it's just PS being to lazy to go deeper and show their values
Before
foo : @{$ref=#/bar}
fooarray : {@{item=}, @{item=}}
test : {1, 2, 3}
bar : True
hello : world
After
foo : True
fooarray : {@{item=True}, @{item=world}}
test : {1, 2, 3}
bar : True
hello : world