如何使用Jayway JsonPath表达式仅保留JSON数组对象中的url字段
问题说明
需求为对指定JSON做结构转换:移除Attachment数组下每个对象中除url之外的所有键值对,外层其余字段保持不变,使用的Jayway JsonPath版本为2.7.0。
原始JSON结构
{ "fields": { "item_name": "mypass\n", "id": "nopass cell", "Attachment": [ { "id": "attaMKW4RR5misdsD", "url": "https://url1.com", "filename": "test-nopass.txt", "size": 17, "type": "text/plain" }, { "id": "attHy3s6MBzce7Qoq", "url": "https://url2.com", "filename": "test-mypass.txt", "size": 28, "type": "text/plain" }, { "id": "atth4oFqzanlk9532", "url": "https://url3.com", "filename": "test- yourpass .txt", "size": 28, "type": "text/plain" } ] } }
期望输出结构
{ "fields": { "item_name": "mypass\n", "id": "nopass cell", "Attachment": [ { "url": "https://url1.com" }, { "url": "https://url2.com" }, { "url": "https://url3.com" } ] } }
注:用户提供的期望示例中url字段后的尾逗号不符合JSON语法规范,实际转换输出为标准合法JSON格式。
实现方法
Jayway JsonPath 2.7.0 不支持仅通过单条只读查询路径直接返回保留完整外层结构、同时裁剪数组内对象字段的结果,需要结合路径定位 + 字段映射 + 回写的流程实现:
- 定位
Attachment数组的JsonPath路径为$.fields.Attachment - 读取该路径下的数组内容,遍历每个元素,重构为仅保留
url键的新对象 - 将重构后的数组写回原路径,即可得到符合要求的JSON结构
参考实现代码(Java)
import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JsonTransformDemo { public static void main(String[] args) { String originalJson = "{\n" + " \"fields\": {\n" + " \"item_name\": \"mypass\\n\",\n" + " \"id\": \"nopass cell\",\n" + " \"Attachment\": [\n" + " {\n" + " \"id\": \"attaMKW4RR5misdsD\",\n" + " \"url\": \"https://url1.com\",\n" + " \"filename\": \"test-nopass.txt\",\n" + " \"size\": 17,\n" + " \"type\": \"text/plain\"\n" + " },\n" + " {\n" + " \"id\": \"attHy3s6MBzce7Qoq\",\n" + " \"url\": \"https://url2.com\",\n" + " \"filename\": \"test-mypass.txt\",\n" + " \"size\": 28,\n" + " \"type\": \"text/plain\"\n" + " },\n" + " {\n" + " \"id\": \"atth4oFqzanlk9532\",\n" + " \"url\": \"https://url3.com\",\n" + " \"filename\": \"test- yourpass .txt\",\n" + " \"size\": 28,\n" + " \"type\": \"text/plain\"\n" + " }\n" + " ]\n" + " }\n" + "}"; DocumentContext jsonContext = JsonPath.parse(originalJson); // 读取原Attachment数组 List<Map<String, Object>> originalAttachments = jsonContext.read("$.fields.Attachment"); List<Map<String, Object>> filteredAttachments = new ArrayList<>(); for (Map<String, Object> item : originalAttachments) { Map<String, Object> newItem = new HashMap<>(); newItem.put("url", item.get("url")); filteredAttachments.add(newItem); } // 回写处理后的数组 jsonContext.set("$.fields.Attachment", filteredAttachments); String resultJson = jsonContext.jsonString(); } }
注意事项
- 不要直接使用
$.fields.Attachment[*].url作为查询路径,该路径只会返回url值组成的一维数组["https://url1.com", "https://url2.com", "https://url3.com"],会丢失所有外层字段结构。 - 处理时不需要单独操作其他外层字段,回写数组时其余字段会自动保留。
内容的提问来源于stack exchange,提问作者singh19jaspreet
相关产品推荐
相关产品推荐

