如何在Powershell中转换为JSON时排除非值对象属性

Edu*_*Uta 9 powershell json powershell-4.0

我有一段可行的代码,但我想知道是否有更好的方法.到目前为止我找不到任何相关内容.以下是事实:

  • 我有一个具有n个属性的对象.
  • 我想使用(ConvertTo-Json)将此对象转换为JSON.
  • 我不想在JSON中包含那些没有被重视的对象属性.

构建对象(不是很重要):

$object = New-Object PSObject
Add-Member -InputObject $object -MemberType NoteProperty -Name TableName -Value "MyTable"
Add-Member -InputObject $object -MemberType NoteProperty -Name Description -Value "Lorem ipsum dolor.."
Add-Member -InputObject $object -MemberType NoteProperty -Name AppArea -Value "UserMgmt"
Add-Member -InputObject $object -MemberType NoteProperty -Name InitialVersionCode -Value ""
Run Code Online (Sandbox Code Playgroud)

我需要改进的行(过滤掉非值属性而不是将它们包含在JSON中)

# So I want to 'keep' and deliver to the JSON only the properties that are valued (first 3).
$object | select -Property TableName, Description, AppArea, InitialVersion | ConvertTo-Json
Run Code Online (Sandbox Code Playgroud)

这条线提供什么:

Results:
{
    "TableName":  "MyTable",
    "Description":  "Lorem ipsum dolor..",
    "AppArea":  "UserMgmt",
    "InitialVersion":  null
}

What I want to obtain:
{
    "TableName":  "MyTable",
    "Description":  "Lorem ipsum dolor..",
    "AppArea":  "UserMgmt"
}
Run Code Online (Sandbox Code Playgroud)

我尝试过和工作过,但我不喜欢它,因为我有更多的属性要处理:

$JSON = New-Object PSObject

if ($object.TableName){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name TableName -Value $object.TableName
}

if ($object.Description){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name Description -Value $object.Description
}

if ($object.AppArea){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name AppArea -Value $object.AppArea
}

if ($object.InitialVersionCode){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name InitialVersionCode -Value $object.InitialVersionCode
}

$JSON | ConvertTo-Json
Run Code Online (Sandbox Code Playgroud)

bea*_*ker 10

像这样的东西?

$object = New-Object PSObject

Add-Member -InputObject $object -MemberType NoteProperty -Name TableName -Value "MyTable"
Add-Member -InputObject $object -MemberType NoteProperty -Name Description -Value "Lorem ipsum dolor.."
Add-Member -InputObject $object -MemberType NoteProperty -Name AppArea -Value "UserMgmt"
Add-Member -InputObject $object -MemberType NoteProperty -Name InitialVersionCode -Value ""

# Iterate over objects
$object | ForEach-Object {
    # Get array of names of object properties that can be cast to boolean TRUE
    # PSObject.Properties - https://msdn.microsoft.com/en-us/library/system.management.automation.psobject.properties.aspx
    $NonEmptyProperties = $_.psobject.Properties | Where-Object {$_.Value} | Select-Object -ExpandProperty Name

    # Convert object to JSON with only non-empty properties
    $_ | Select-Object -Property $NonEmptyProperties | ConvertTo-Json
}
Run Code Online (Sandbox Code Playgroud)

结果:

{
    "TableName":  "MyTable",
    "Description":  "Lorem ipsum dolor..",
    "AppArea":  "UserMgmt"
}
Run Code Online (Sandbox Code Playgroud)

  • 做得很好; 但是,我建议在“ Where-Object”脚本块中使用“ $ null -ne $ _。Value”,以免意外删除“ 0”和“ $ False”值。 (2认同)

小智 6

为此,我的个人资料中有以下功能。优点:我可以通过管道将对象集合传递给它,并从管道上的所有对象中删除空值。

Function Remove-Null {
    [cmdletbinding()]
    param(
        # Object to remove null values from
        [parameter(ValueFromPipeline,Mandatory)]
        [object[]]$InputObject,
        #By default, remove empty strings (""), specify -LeaveEmptyStrings to leave them.
        [switch]$LeaveEmptyStrings
    )
    process {
        foreach ($obj in $InputObject) {
            $AllProperties = $obj.psobject.properties.Name
            $NonNulls = $AllProperties |
                where-object {$null -ne $obj.$PSItem} |
                where-object {$LeaveEmptyStrings.IsPresent -or -not [string]::IsNullOrEmpty($obj.$PSItem)}
            $obj | Select-Object -Property $NonNulls
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

一些用法示例:

$AnObject = [pscustomobject]@{
    prop1="data"
    prop2="moredata"
    prop5=3
    propblnk=""
    propnll=$null
}
$AnObject | Remove-Null

prop1 prop2    prop5
----- -----    -----
data  moredata     3

$ObjList =@(
    [PSCustomObject]@{
        notnull = "data"
        more = "sure!"
        done = $null
        another = ""
    },
    [PSCustomObject]@{
        notnull = "data"
        more = $null
        done = $false
        another = $true
    }
)
$objList | Remove-Null | fl #format-list because the default table is misleading

notnull : data
more    : sure!

notnull : data
done    : False
another : True
Run Code Online (Sandbox Code Playgroud)

  • 优雅且做得很好,我现在已将其添加到我的几个模块中 (2认同)