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

使用json-simple解析嵌套JSON时遇类型转换与空值问题求助

问题分析与解决方案

首先,你的代码存在几个关键错误导致解析失败:

  • characterizations_values 是JSON数组(而非Map),直接强转为Map<String,String>会导致类型不匹配
  • 错误地创建新JSONObject来包装sheet,而非直接从原数据中提取已存在的sheet对象
  • 未逐层处理嵌套的数组和对象结构

以下是修正后的解析方案,严格按照你提出的逐层解析顺序实现:

修正后的代码

import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.FileReader;
import java.io.IOException;

public class JsonParserFix {
    public static void main(String[] args) {
        JSONParser parser = new JSONParser();
        try (FileReader reader = new FileReader("your-json-file-path.json")) {
            // 解析根JSON对象
            JSONObject rootObj = (JSONObject) parser.parse(reader);
            
            // 1. 获取characterizations_values数组(注意是数组类型)
            JSONArray charValuesArray = (JSONArray) rootObj.get("characterizations_values");
            JSONObject charValueItem = (JSONObject) charValuesArray.get(0);
            
            // 2. 提取sheet对象
            JSONObject sheetObj = (JSONObject) charValueItem.get("sheet");
            
            // 3. 解析my-title部分
            JSONArray myTitleArray = (JSONArray) sheetObj.get("my-title");
            JSONObject titleContent = (JSONObject) myTitleArray.get(0);
            
            // 获取title内的字段
            String number = (String) titleContent.get("number");
            String numberedPart = (String) titleContent.get("numbered-part");
            
            // 解析嵌套的documents数组
            JSONArray docsOuterArr = (JSONArray) titleContent.get("documents");
            JSONArray docsInnerArr = (JSONArray) docsOuterArr.get(0);
            JSONObject docObj = (JSONObject) docsInnerArr.get(0);
            String docName = (String) docObj.get("document_name");
            JSONArray docCategories = (JSONArray) docObj.get("document-category");
            
            // 4. 解析my-notes部分
            JSONArray myNotesArray = (JSONArray) sheetObj.get("my-notes");
            JSONObject notesContent = (JSONObject) myNotesArray.get(0);
            JSONObject dimensions = (JSONObject) notesContent.get("dimensions");
            
            JSONObject enclosing = (JSONObject) dimensions.get("enclosing");
            double testOneEnclosing = (double) enclosing.get("test-one");
            long testTwoEnclosing = (long) enclosing.get("test-two");
            
            JSONObject enclosingExtra = (JSONObject) dimensions.get("enclosing-extra");
            double testOneExtra = (double) enclosingExtra.get("test-one");
            long testTwoExtra = (long) enclosingExtra.get("test-two");
            
            // 测试输出
            System.out.println("Number: " + number);
            System.out.println("Document Name: " + docName);
            System.out.println("Test One Enclosing: " + testOneEnclosing);
            
        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }
    }
}

关键注意事项

  • 严格匹配类型:JSON中[]对应JSONArray,{}对应JSONObject,必须准确强制类型转换
  • 逐层提取:从根对象开始向下逐层获取,不要跨层级操作
  • 数组元素处理:即使数组只有一个元素,也要先获取数组再取第一个元素(比如characterizations_values和my-title)
  • 数值类型区分:json-simple会将整数解析为Long,浮点数解析为Double,避免错误转换

替代方案建议

如果觉得json-simple的手动类型转换过于繁琐,可以改用Jackson或Gson库,它们支持将JSON直接映射到Java实体类,省去逐层解析的麻烦:

以Gson为例:

  1. 创建对应JSON结构的实体类:
public class CharacterizationsValue {
    private String filename;
    private Sheet sheet;
    // getter/setter
}

public class Sheet {
    @SerializedName("my-title")
    private List<MyTitle> myTitle;
    @SerializedName("my-notes")
    private List<MyNote> myNotes;
    // getter/setter
}

// 其他嵌套实体类(MyTitle、MyNote等)省略...
  1. 解析代码:
Gson gson = new Gson();
String jsonString = // 读取JSON文件内容
CharacterizationsValue[] values = gson.fromJson(jsonString, CharacterizationsValue[].class);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:06:20