You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell递归函数实现JSON转点表示法求助

PowerShell实现JSON转点表示法扁平化格式

需求与示例

输入常规JSON文件(如AppSettings配置),需将嵌套结构转换为保留完整路径的扁平化格式,用点连接层级键名。

输入示例:

{
    "Logging": {
        "MinLevel": {
            "Default": "Information",
            "Override": {
                "Host": "Warning"
            }
        },
        "Properties": {
            "ApplicationName": "My App"
        }
    },
    "ConnectionStrings": {
        "DefaultConnection": "string"
    }
}

期望输出:

"Logging.MinLevel.Default" : "Information"
"Logging.MinLevel.Override.Host" : "Warning"
"Logging.Properties.ApplicationName" : "My App"
"ConnectionStrings.DefaultConnection" : "string"

原递归函数问题分析

你编写的ConvertTo-DotNotation函数核心思路正确,但存在几个关键问题:

  • 未正确累积当前层级的键路径,递归时未拼接父级键名
  • 未收集递归返回的所有结果,也未处理非对象值的输出格式
  • 循环内提前return导致仅处理第一个属性就终止函数

完善后的递归函数

function ConvertTo-DotNotation {
    param(
        [pscustomobject] $jsonObject,
        [string] $separator = ":",
        [string] $currentPath = ""
    )

    $results = @()

    # 遍历对象所有属性
    foreach ($property in $jsonObject.PSObject.Properties) {
        $key = $property.Name
        $value = $property.Value
        # 拼接当前完整路径
        $newPath = if ($currentPath) { "$currentPath.$key" } else { $key }

        if ($value -is [pscustomobject]) {
            # 递归处理嵌套对象,收集结果
            $results += ConvertTo-DotNotation -jsonObject $value -separator $separator -currentPath $newPath
        } else {
            # 格式化非对象值,字符串类型添加引号
            $formattedValue = if ($value -is [string]) { "`"$value`"" } else { $value }
            $results += "`"$newPath`" $separator $formattedValue"
        }
    }

    return $results
}

# 使用示例
$appSettings = Get-Content -Path "./AppSettingsJSON/regular_json_file.json" | ConvertFrom-Json
$flattenedSettings = ConvertTo-DotNotation -jsonObject $appSettings

# 输出结果
$flattenedSettings

关键改进点

  • 用$results数组收集所有输出,避免提前终止函数
  • 正确拼接父级路径与当前键名,确保层级完整
  • 对字符串值添加引号,保持输出格式统一
  • 改用PSObject.Properties直接获取属性,比Get-Member更高效

替代实现方案(非递归)

若不想用递归,可通过栈迭代处理嵌套对象,避免递归深度限制问题:

function ConvertTo-DotNotationIterative {
    param(
        [pscustomobject] $jsonObject,
        [string] $separator = ":"
    )

    $stack = [System.Collections.Stack]::new()
    $stack.Push(@{ Path = ""; Object = $jsonObject })
    $results = @()

    while ($stack.Count -gt 0) {
        $item = $stack.Pop()
        $currentPath = $item.Path
        $currentObj = $item.Object

        foreach ($property in $currentObj.PSObject.Properties) {
            $key = $property.Name
            $value = $property.Value
            $newPath = if ($currentPath) { "$currentPath.$key" } else { $key }

            if ($value -is [pscustomobject]) {
                $stack.Push(@{ Path = $newPath; Object = $value })
            } else {
                $formattedValue = if ($value -is [string]) { "`"$value`"" } else { $value }
                $results += "`"$newPath`" $separator $formattedValue"
            }
        }
    }

    # 反转结果匹配原JSON顺序(栈为后进先出结构)
    return $results | Reverse
}

# 使用示例
$flattenedSettingsIterative = ConvertTo-DotNotationIterative -jsonObject $appSettings
$flattenedSettingsIterative

内容的提问来源于stack exchange,提问作者DL3001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:42:45