难以构建PowerShell函数以展开JSON文档表

问题描述

我构建了一个递归解决方案,以读取JSON文档并输出平坦表。现在我想反转操作,但是很难找出孤子。我需要将其安装在PowerShell中,因为我只想将其添加到现有模块中。

我在此处发布了有关我的展平代码的信息:https://stackoverflow.com/a/63499156/13224569

我有一个部分解决方案,但是很短。这是代码:

$a = '.person.pets[0].color.black.toy.foo' -split '\.'
$b = '.john.harold.cravener' -split '\.'
$z = '.john.is.content' -split '\.'

$m = @{}
$c = @{}
$p = @{}
$pk = $null
$firstTime = $true

foreach($i in $a[1..($a.Count-1)]) {
    $c = @{$i = $null}
    if($firstTime){
        $m = $c
        $firstTime = $false
    }
    
    if($p -and $pk) {
        $p[$pk] = $c
    }
    $p = $c
    $pk = $i
}
$m
exit

这是它的输出:

PS D:\> .\tester.ps1 | ConvertTo-Json -Depth 20
{
  "person": {
    "pets[0]": {
      "color": {
        "black": {
          "toy": {
            "foo": null
          }
        }
      }
    }
  }
}

我的第一个挑战是,我不知道如何继续下一行并将其存储到现有的$ m变量中。我不知道在PowerShell / .Net Core中引用此var的方式。

第二个挑战是如何处理数组,但我什至还没有开始。

任何人和所有帮助/建议将不胜感激!

解决方法

经过一些研究,以及大量的工作和调试,我找到了一个解决方案。从我到目前为止的测试来看,它运行良好。它基于simonw的python代码here。尽管我的解决方案需要安装在PowerShell中,但它不是直接端口,而是非常接近的端口。大多数修改都是基于PowerShell和Python处理某些事情的方式上的差异。主要功能是 ConvertFrom-JhcUtilJsonTable ,该功能又取决于三个帮助器功能。这都是他们。

function ConvertFrom-JhcUtilJsonTable {
    param (
        [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
        [System.Collections.Hashtable]
        $jsonHashTable
    )
    begin {}
    
    process {
        foreach ($h in $jsonHashTable) {
            
            $m = @{}
            foreach ($k in $h.Keys) {
                $current = $m
                $val = $h[$k]
                $k = ($k -replace '\]','') -replace '\[','.'
                $bits = $k.split('.')
                $path = $bits[1..($bits.Count - 1)]

                $count = 0
    
                foreach ($bit in $path) {
                    $count++
                    if ($v = $current.item($bit)) {
                        $current[$bit] = $v
                    }
                    else {
                        if ($count -eq $path.Count) {
                            $current[$bit] = $val
                        }
                        else {
                            $current[$bit] = @{}
                        }
                    }
                    $current = $current[$bit]
                }
            }
            
            intKeyHashToLists -obj $m
            #--python code had a buit about handling root units e.g. {'$empty': '{}'} - need to add that
        }
    }
    
    end {}
}


#---helper function for ConvertFrom-JhcUtilJsonTable
#
function isType {
    param (
        [Parameter(Mandatory)]
        [System.Object]
        $obj,[Parameter(Mandatory)]
        [ValidateSet('Hashtable','Object[]')]
        [System.String]
        $typeName
    )
    
    $t = $obj.GetType()

    if ($t.Name -eq $typeName) {
        return $true
    }
    return $false
}

#---helper function for ConvertFrom-JhcUtilJsonTable
#
function allKeysDigits {
    param (
        [Parameter(Mandatory)]
        [System.Collections.Hashtable]
        $h
    )

    foreach ($k in $h.Keys) {
        
        if ($k -match '^0\d') {
            return $false
        }
        
        if ($k -notmatch '^\d+$') {
            return $false  
        }
    }
    return $true
}

#---helper function for ConvertFrom-JhcUtilJsonTable
#
function intKeyHashToLists {
    param (
        [Parameter(Mandatory)]
        [System.Object]
        $obj
    )
    
    if (isType -obj $obj -typeName 'Hashtable') {
        if ($obj -and (allKeysDigits -h $obj)) {
            $a = @()
            foreach ($k in ($obj.Keys | Sort-Object) ) {
                $a += intKeyHashToLists -obj $obj.item($k)
            }

            return,$a  #--- adding the comma forces this to retun an array even when it's a single element
        }
        else {
            $h = @{}
            foreach ($k in $obj.Keys) {
                $h[$k] = intKeyHashToLists -obj $obj.item($k)
            }
            return $h
        }
    }
    elseif (isType -obj $obj -typeName 'Object[]') {
        return ( $obj | ForEach-Object { intKeyHashToLists -obj $_ } )
    }
    else {
        return $obj
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...