首页 > 解决方案 > 如何将此嵌套 JSON 转换为 Datatable

问题描述

[{
    "change": {
        "action": "updated",
        "record_id": 71176961,
        "record": {
            "time_entry": {
                "date_at": "2019-04-04",
                "minutes": 197
            }
        }
    }
}, {
    "change": {
        "action": "created",
        "record_id": 71209354,
        "record": {
            "time_entry": {
                "date_at": "2019-04-04",
                "minutes": 15
            }
        }
    }
}]

我需要将其转换json为,2D powershell data table以便将bulkcopy其转换为database table. 所以我在 json 中有 2 个级别(3D)(更改和记录更改)。我可以做类似的事情(从json转换后):

.change | Select-Object action, record_id, @{n='date_at';e={$_.record.time_entry.date_at}}, @{n='minutes';e={$_.record.time_entry.minutes}}| Out-DataTable

但问题是,记录实体可能非常大(并且会增长),我不想在代码中指定所有名称。所以我想将第二级(记录)转换为数据表,并在代码中有change.action、change.record_id(因为“change”结构永远不会改变,但“record”会)。

标签: jsonpowershell

解决方案


这对我有用:

$object = @"
[{
    "change": {
        "action": "updated",
        "record_id": 71176961,
        "record": {
            "time_entry": {
                "date_at": "2019-04-04",
                "minutes": 197
            }
        }
    }
}, {
    "change": {
        "action": "created",
        "record_id": 71209354,
        "record": {
            "time_entry": {
                "date_at": "2019-04-04",
                "minutes": 15
            }
        }
    }
}]
"@ | ConvertFrom-Json 


    #------------------------------------------------------------------------
    function Get-DataTable
    #------------------------------------------------------------------------
    {

        param(
            [PSCustomObject]$srcObject,
            [System.Data.DataTable]$dt,
            [System.Data.DataRow]$row = $null
        )

        foreach( $property in $srcObject.PSObject.Properties ) {

            if( $property.Value -is [PSCustomObject] ) {
                $row = (Get-DataTable -srcObject $property.Value -dt $dt -row $row).Row
            }
            else {
                if( $row -eq $null ) {
                    if( $dt.Columns.IndexOf($property.Name) -lt 0 ) {
                        [void]$dt.Columns.Add($property.Name, [string]::Empty.GetType() )
                    }
                }
                else {
                    $row.Item($property.Name) = $property.value
                }

            }
        }

        return @{ 'Row' = $row }
    }

    $dt = New-Object System.Data.DataTable

    # create columns
    foreach( $item in $object ) {
        Get-DataTable -srcObject $item -dt $dt | out-null
    }

    # fill datatable
    foreach( $item in $object ) {
        $row = $dt.NewRow()
        $row = (Get-DataTable -srcObject $item -dt $dt -row $row).Row
        [void]$dt.Rows.Add( $row )
    }

    $dt

推荐阅读