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

如何用F#遍历未知结构的任意JSON树?求实现示例

嘿,我之前刚好用Newtonsoft.Json.Linq实现过未知结构JSON的遍历,给你一个能直接用的F#示例,完全满足你的需求——每个节点都能拿到名称、类型,还能递归遍历结构和数组!

第一步:准备依赖

首先确保你的项目已经安装了Newtonsoft.Json包,用.NET CLI的话可以跑这个命令:

dotnet add package Newtonsoft.Json

核心遍历实现

这个函数用F#的模式匹配来精准处理不同类型的JSON节点,递归遍历所有层级:

open Newtonsoft.Json.Linq

let rec traverseJson (parentName: string option) (token: JToken) =
    // 确定当前节点的显示名称
    let nodeName = 
        match parentName with
        | Some name -> name
        | None -> "根节点"

    // 根据Token类型分支处理
    match token with
    | :? JObject as obj ->
        printfn "* 节点名称: %s | 类型: 结构(JObject)" nodeName
        // 遍历JObject的所有属性,递归处理属性值
        for prop in obj.Properties() do
            traverseJson (Some prop.Name) prop.Value
    | :? JArray as arr ->
        printfn "* 节点名称: %s | 类型: 数组(JArray)" nodeName
        // 遍历数组的每个元素,用索引作为元素名称
        arr |> Seq.iteri (fun idx elem ->
            let elemName = sprintf "数组元素[%d]" idx
            traverseJson (Some elemName) elem
        )
    | :? JValue as value ->
        // 叶子节点,输出具体类型和值
        let valueType = value.Type.ToString()
        printfn "* 节点名称: %s | 类型: 叶子节点(%s) | 值: %O" nodeName valueType value.Value
    | _ ->
        // 处理其他少见的JToken类型(比如构造器、原始JSON等)
        printfn "* 节点名称: %s | 类型: 未知(%s)" nodeName token.Type.ToString()

示例用法

我们用一个结构复杂的JSON来测试,看看遍历效果:

// 构造一个未知结构的示例JSON
let sampleJson = """
{
    "user": {
        "name": "Alice",
        "age": 30,
        "hobbies": ["reading", "hiking", {"type": "sports", "level": "beginner"}]
    },
    "isActive": true,
    "lastLogin": null
}
"""

// 解析JSON为根节点
let rootToken = JToken.Parse(sampleJson)

// 启动遍历
printfn "开始遍历JSON树:"
traverseJson None rootToken

输出结果

运行后会得到清晰的节点信息:

开始遍历JSON树:
* 节点名称: 根节点 | 类型: 结构(JObject)
* 节点名称: user | 类型: 结构(JObject)
* 节点名称: name | 类型: 叶子节点(String) | 值: Alice
* 节点名称: age | 类型: 叶子节点(Int32) | 值: 30
* 节点名称: hobbies | 类型: 数组(JArray)
* 节点名称: 数组元素[0] | 类型: 叶子节点(String) | 值: reading
* 节点名称: 数组元素[1] | 类型: 叶子节点(String) | 值: hiking
* 节点名称: 数组元素[2] | 类型: 结构(JObject)
* 节点名称: type | 类型: 叶子节点(String) | 值: sports
* 节点名称: level | 类型: 叶子节点(String) | 值: beginner
* 节点名称: isActive | 类型: 叶子节点(Boolean) | 值: True
* 节点名称: lastLogin | 类型: 叶子节点(Null) | 值: <null>

关键细节说明

  • 节点名称处理:根节点默认叫“根节点”,对象属性用属性名,数组元素用「数组元素[索引]」标识,确保每个节点都有清晰的名称。
  • 类型判断:通过模式匹配直接区分「结构(JObject)」「数组(JArray)」「叶子节点(JValue)」,叶子节点还会显示具体的子类型(比如String、Int32)。
  • 递归遍历:遇到对象或数组时自动递归处理子节点,不管JSON嵌套多少层都能遍历到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:36:05