PowerShell嵌套JSON解析为单行CSV及导出UTF编码报错优化方案
嵌套JSON解析导出CSV优化方案
现有实现的核心问题
- 手动拼接逗号字符串的方式,遇到字段含逗号、双引号、换行时会直接破坏CSV格式,内置命令可自动处理转义逻辑
- 嵌套多数组的笛卡尔积逻辑(比如单个MasterSeries对应多条Points)需要多层嵌套循环手动维护,冗余度高
- 导出编码不匹配,PowerShell 5.1默认输出ASCII编码,非英文字段导入时就会触发UTF编码报错
标准化实现步骤
1. 替换手动拼接逻辑,使用内置对象展平
不需要手动逐字段拼字符串,先把嵌套层级的属性合并为统一的PSCustomObject,自动处理特殊字符转义。
针对给出的固定JSON结构,可直接用如下展平代码:
# 先将原始JSON文本解析为PowerShell对象 $json = Get-Content -Raw -Path "你的JSON文件路径.json" | ConvertFrom-Json # 三层嵌套遍历,生成扁平化对象列表 $flattenedRows = foreach ($rootItem in $json.value) { foreach ($masterSeriesItem in $rootItem.MasterSeries) { foreach ($pointItem in $masterSeriesItem.Points) { [PSCustomObject]@{ # 根层级属性 Root_ExternalKey = $rootItem.ExternalKey Root_PortfolioId = $rootItem.PortfolioId Root_InceptionDate = $rootItem.InceptionDate Root_TerminationDate = $rootItem.TerminationDate Root_Version = $rootItem.Version Root_SourceRef = $rootItem.SourceRef # MasterSeries层级属性 Master_ExternalKey = $masterSeriesItem.ExternalKey Master_Version = $masterSeriesItem.Version Master_IsDeleted = $masterSeriesItem.IsDeleted Master_SourceRef = $masterSeriesItem.SourceRef # Points层级属性 Point_Date = $pointItem.Date Point_Name = $pointItem.Name Point_Type = $pointItem.Type Point_Status = $pointItem.Status Point_Version = $pointItem.Version } } } }
如果后续JSON结构会变动,不需要手动列字段,可以用通用递归展平函数适配任意嵌套结构:
function Flatten-NestedObject { param( [Parameter(ValueFromPipeline)]$InputObject, $NamePrefix = "" ) process { $result = [ordered]@{} foreach ($prop in $InputObject.PSObject.Properties) { $currentKey = if ($NamePrefix) { "$NamePrefix`_$($prop.Name)" } else { $prop.Name } # 处理数组类型属性,遍历每个数组元素递归展平 if ($prop.Value -is [System.Array]) { foreach ($arrayItem in $prop.Value) { $childResult = Flatten-NestedObject -InputObject $arrayItem -NamePrefix $currentKey foreach ($childProp in $childResult.PSObject.Properties) { $result[$childProp.Name] = $childProp.Value } } } # 处理嵌套对象类型属性,递归展平 elseif ($prop.Value -is [PSCustomObject]) { $childResult = Flatten-NestedObject -InputObject $prop.Value -NamePrefix $currentKey foreach ($childProp in $childResult.PSObject.Properties) { $result[$childProp.Name] = $childProp.Value } } # 基础类型属性直接赋值 else { $result[$currentKey] = $prop.Value } } [PSCustomObject]$result } } # 通用展平调用,自动适配任意嵌套层级 $flattenedRows = $json.value | Flatten-NestedObject
2. 解决编码报错的导出配置
不要使用Out-File手动写CSV,直接用PowerShell内置的Export-Csv命令,指定兼容所有工具的UTF-8带BOM编码:
- PowerShell 7+ 写法:
$flattenedRows | Export-Csv -Path "Export.csv" -NoTypeInformation -Encoding utf8BOM
- PowerShell 5.1 写法(5.1的
UTF8参数默认输出带BOM,可被Excel等工具正常识别):
$flattenedRows | Export-Csv -Path "Export.csv" -NoTypeInformation -Encoding UTF8
方案优势
- 内置命令自动处理字段转义,不会因为字段含特殊字符破坏CSV格式
- 递归展平逻辑可适配任意JSON结构变动,不需要手动修改逐层级的拼接代码
- 指定的带BOM UTF-8编码可避免导入时的编码识别错误
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

