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

如何使用Argonaut将嵌套JSON数组解析为Scala字符串数组并解决API识别问题

解决Argonaut API识别失败、提取JSON嵌套query字段的实操方案

核心问题排查

  • 所有decodeOption、Parse.parse、codec3识别失败的根本原因都是导入缺失、版本不匹配、参考内容过老:
    • Argonaut的所有扩展方法(比如字符串上的decodeOption)都是靠隐式转换实现的,必须显式导入argonaut.Argonaut._才能触发,漏了这个导入所有方法都会报找不到符号
    • 老教程里提到的codec3是给3个字段的case类生成编解码器的老API,新版本Argonaut调整了该系列方法的签名和引用路径,直接抄多年前的社区代码自然识别不到
    • 你提供的JSON本身存在语法错误:最外层多了一个冗余的闭合大括号,就算API配对正确,解析也会直接失败,修正后的正确JSON格式如下:
      {
        "TestModel" : [
          {"query" : "select * from ci_lmaggregation.elementstest where hash_aggregation_key = 0 ALLOW FILTERING "},
          {"query" : "select * from ci_lmaggregation.elementstest where hash_aggregation_key = 1 ALLOW FILTERING "},
          {"query" : "select * from ci_lmaggregation.elementstest where hash_aggregation_key = 2 ALLOW FILTERING "}
        ]
      }
      
  • 需求完全可以实现和Python一致的简易取数逻辑,不需要提前定义复杂的case类或手写冗余编解码器

零类型绑定的最简实现(和Python JSON操作逻辑对齐)

不需要提前定义任何业务case类,直接按JSON路径取值,即可拿到所有query字符串:

// 必须导入完整的Argonaut扩展包,解决API找不到的问题
import argonaut._
import Argonaut._

val inputPath = "[path]/FeatureMapping.json"
val jsonContent = scala.io.Source.fromFile(inputPath).mkString.trim
// 解析JSON字符串,返回Either[ParseError, Json]
val parseResult = Parse.parse(jsonContent)

// 按路径直接取所有query值,组装成字符串数组
val queryArray = parseResult.toOption.map { rootJson =>
  // 直接递归查找TestModel字段下所有嵌套的query值
  (rootJson \\ "TestModel" --\\ "query")
    .flatMap(_.as[String].toOption)
}.getOrElse(Nil)

上述代码完全等价于Python中的简易取数逻辑:

# 等价的Python实现
import json
with open(inputPath) as f:
    data = json.load(f)
query_array = [item["query"] for item in data["TestModel"]]

强类型场景的实现方式

如果需要把JSON映射成强类型对象方便后续维护,只需要定义和JSON结构对应的case类,用对应字段数量的casecodecN生成编解码器即可,不需要用和结构不匹配的codec3:

// 1. 定义和JSON结构完全匹配的case类
case class QueryEntry(query: String)
case class ModelWrapper(TestModel: List[QueryEntry])

// 2. 为只有1个字段的QueryEntry生成编解码器(当前JSON结构没有3个字段的对象,完全用不到codec3)
implicit val queryCodec: CodecJson[QueryEntry] = casecodec1(QueryEntry.apply, QueryEntry.unapply)("query")
implicit val wrapperCodec: CodecJson[ModelWrapper] = casecodec1(ModelWrapper.apply, ModelWrapper.unapply)("TestModel")

// 3. 直接解码成强类型对象提取字段
val typedQueries = jsonContent
  .decodeOption[ModelWrapper]
  .map(_.TestModel.map(_.query))
  .getOrElse(Nil)

避坑提示

  • 导入代码必须放在文件顶部,不能写在函数内部,否则隐式转换不会生效
  • 参考社区教程时要匹配当前使用的Argonaut版本,6.2之后的版本和6.1及更早版本的API存在不兼容改动
  • 写完JSON内容先做语法校验,避免冗余括号、逗号这类低级错误导致解析失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 08:54:06