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

Python中如何通过带过滤条件的JSONPath更新节点?

问题

需要通过带过滤条件的JSONPath(例如包含[@.field]的表达式)更新JSON节点,但使用jsonpath_ng库的尝试均未成功。以下是测试代码及运行输出:

测试代码
import json
import jsonpath_ng.ext
import jsonpath_ng
from hashlib import md5

# 尝试将 {"a": {"b": "c"}} 转为 {"a": {1: 2}}
for jpath_str in ["$.a", "$[?(@.b)]", "$.a.b.`parent`"]:
    for jp_lib in [jsonpath_ng, jsonpath_ng.ext]:
        obj = json.loads('{"a": {"b": "c"}}')
        print(f"jp_lib={jp_lib.__name__:<15} json_path_str={jpath_str:<15}", end="\t")
        try:
            # 查找节点并尝试更新
            jpath = jp_lib.parse(jpath_str)
            matches = jpath.find(obj)
            if not matches:
                print("--> 未找到节点")
                continue
            for match in matches:
                print(f"match={md5(str(match).encode()).hexdigest()[:-10]}", end="\t")
            jpath.update(obj, {1:2})
            print(f"--> 结果={obj}", end="\t")
            if "b" in obj['a']: print(" -->更新静默失败", end="\t")

        except Exception as ex:
            print(f"--> 异常={type(ex).__name__}({ex})")
        print()
运行输出
jp_lib=jsonpath_ng     json_path_str=$.a                match=6d6c26aced0709ca568e84    --> 结果={'a': {1: 2}}    
jp_lib=jsonpath_ng.ext json_path_str=$.a                match=6d6c26aced0709ca568e84    --> 结果={'a': {1: 2}}    
jp_lib=jsonpath_ng     json_path_str=$[?(@.b)]          --> 异常=JsonPathLexerError(Error on line 1, col 2: Unexpected character: ? )  
jp_lib=jsonpath_ng.ext json_path_str=$[?(@.b)]          match=6de1848d9db98d7d1c6766    --> 结果={'a': {'b': 'c'}}     -->更新静默失败  
jp_lib=jsonpath_ng     json_path_str=$.a.b.`parent`     match=6d6c26aced0709ca568e84    --> 异常=NotImplementedError() 
jp_lib=jsonpath_ng.ext json_path_str=$.a.b.`parent`     match=6d6c26aced0709ca568e84    --> 异常=NotImplementedError() 
问题分析与解决方案
  1. 基础路径$.a更新正常:不管是jsonpath_ng还是jsonpath_ng.ext,直接定位到节点a时,update方法能正常替换值,符合预期。
  2. 过滤路径$[?(@.b)]失效:
    • 原生jsonpath_ng不支持过滤表达式([?()]),会直接抛出语法错误。
    • jsonpath_ng.ext能找到匹配的节点,但update方法无法生效。这是因为过滤表达式匹配的是整个根对象$,而非a节点,调用update会尝试替换根对象,但传入的{1:2}并没有覆盖a,导致原节点保留。
      解决方法:调整过滤路径为$.a[?(@.b)],直接定位到包含b字段的a节点,这样update就能正确替换a的值。
  3. parent语法未实现:不管哪个库,$.a.b.parent``语法都未实现,抛出NotImplementedError,暂时无法通过这种方式获取父节点并更新,建议直接定位目标节点或调整路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:02:49