问题描述
我有两种不同的JSON,如果仅在Address(数组)下存在,我想从JSON对象中删除街道。我正在尝试在Powershell中执行此操作。我可以使脚本工作并删除街道,但是如果地址具有streets属性,我只想运行命令的排除行。
p.join()
第二个JSON-由于没有街道,所以不想为第二个JSON运行排除行
{
"Customer": [{
"id": "123"
}],"address": [{
"$type": "Home","name": "Houston","streets": [{
"name": "Union","postalCode": "10"
}]
},{
"$type": "Office","name": "Hawai","streets": [{
"name": "Rock","postalCode": "11"
}]
}
]
}
Powershell脚本
{
"Customer": [{
"id": "123"
}],"name": "Houston"
},"name": "Hawai"
}
]
}
解决方法
T-Me's helpful answer是最可靠的方法,因为它查找的是属性本身的存在,而不是非空的 values 。
如果您愿意假设缺少值也意味着缺少属性本身,则可以采用以下捷径,效果更好:
$hasAtLeastOneStreet = 0 -ne
(@((Get-Content Test.json -Raw | ConvertFrom-Json).address.streets) -ne $null).Count
.address.streets
使用member enumeration提取所有streets
的值,@(...)
确保结果是一个数组,-ne $null
过滤掉任何$null
值,然后.Count
对其元素进行计数。
注意:该表达式应该更简单:$null -ne (Get-Content Test.json -Raw | ConvertFrom-Json).address.streets
但是由于 bug 当前无法执行-请参阅底部。
进行演示(输入字符串是JSON文档的压缩的单行版本):
'{"Customer":[{"id":"123"}],"address":[{"$type":"Home","name":"Houston","streets":[{"name":"Union","postalCode":"10"}]},{"$type":"Office","name":"Hawai","streets":[{"name":"Rock","postalCode":"11"}]}]}','{"Customer":[{"id":"123"}],"name":"Houston"},"name":"Hawai"}]}' |
foreach {
"has street values: " +
(0 -ne @(((ConvertFrom-Json $_).address.streets) -ne $null).Count)
}
上面的结果表明,第一个JSON文档具有street
值,而第二个JSON文档没有。
has street values: True
has street values: False
注意:您应该可以将测试表达式简化为以下内容,但是由于至少在PowerShell 7.0上出现了 bug ,因此无法正常工作:
# !! SHOULD worm,but as of PowerShell 7.0,DOESN'T,due to a bug relating
# to the presence of two or more [pscustomobject] instances in the address array:
$hasAtLeastOneStreet =
$null -ne (Get-Content Test.json -Raw | ConvertFrom-Json).address.streets
通常,缺少任何streets
属性值都将导致$null
,但是[pscustomobject]
数组中存在两个或更多.address
实例,则意外地返回了$null
个值的数组。
如果您只想执行代码if
,address
具有member
streets
,则可以测试一下:
if (
($FileContent.address | Get-Member -MemberType NoteProperty -Name "streets") -ne $null
){
$FileContent.address = $FileContent.address | Select-Object * -ExcludeProperty streets
}