JSONPath返回JProperty而非JObject,如何查询指定JSON目标值?
解决JSONPath返回JProperty而非JObject的问题,获取目标public值
首先咱们得理清需求逻辑:先找到roles里name为"targets/abc"的项,取出它的keyids[0],再用这个keyid去keys节点里找到对应的keyval.public值。
你的原JSONPath表达式问题出在两个核心点:
keys是对象而非数组,不能用数组过滤的[?()]语法来访问它的属性;- 嵌套的JSONPath引用写法不符合规范,没法正确关联两个节点的值。
方案1:分两步用JSONPath + 代码处理(适配Newtonsoft.Json场景)
纯JSONPath很难直接实现“用一个节点的值作为另一个对象的键”这种动态引用,所以拆成两步更靠谱:
先获取目标keyid:
$.signed.delegations.roles[?(@.name == 'targets/abc')].keyids[0]这个表达式会返回目标字符串:
d8674eb06f5aac8d003b2f309e302fd0a82414074acc9a626e0b447704f2a2b8再用这个keyid构造访问路径,直接取值:
// 假设你的JSON已解析为JObject实例jsonObj var targetKeyId = jsonObj.SelectToken("$.signed.delegations.roles[?(@.name == 'targets/abc')].keyids[0]").Value<string>(); var publicKey = jsonObj.SelectToken($"$.signed.delegations.keys['{targetKeyId}'].keyval.public").Value<string>();
方案2:用Linq to JSON直接关联(更简洁直观)
如果用Newtonsoft.Json的Linq API,直接关联两个节点能避开JSONPath的局限性,代码可读性也更强:
var jsonObj = JObject.Parse(yourJsonString); // 定位目标role的keyid var targetKeyId = jsonObj["signed"]["delegations"]["roles"] .First(role => role["name"].Value<string>() == "targets/abc")["keyids"][0] .Value<string>(); // 用keyid获取对应的public值 var publicKey = jsonObj["signed"]["delegations"]["keys"][targetKeyId]["keyval"]["public"] .Value<string>();
为什么原表达式返回JProperty?
当你用数组过滤语法去访问对象属性时,Newtonsoft的JSONPath实现会把对象的键值对当成可枚举的项,返回的是属性项(JProperty)而非属性值(JObject/JValue),这就导致你没法直接链式访问keyval.public。
内容的提问来源于stack exchange,提问作者D.R.
相关产品推荐
相关产品推荐

