JSONPath语法详解与Python实战:告别硬编码,高效查询JSON数据
1. 为什么你需要JSONPath从“硬编码”到“声明式”查询的转变如果你写过Python来处理JSON数据下面这个场景你一定不陌生拿到一个嵌套了七八层的API响应为了取出最深处某个字段的值你不得不写一长串的data[‘level1’][‘level2’][‘target’]。代码又臭又长一旦数据结构稍有变动比如中间某个键名改了或者返回的层级变了你的代码就得跟着大改。更头疼的是当你想提取一组结构相同但位置分散的数据时比如一个商品列表里所有商品的价格用传统的字典键值访问方式你就得写循环逻辑瞬间复杂起来。这就是JSONPath要解决的问题。它之于JSON就像XPath之于XML是一种专门用于在JSON结构中定位和提取数据的查询语言。它的核心思想是“声明式查询”你只需要告诉程序“我想要什么”比如所有价格高于100的商品ID而不是“我怎么一步步去拿”。这种转变带来的好处是巨大的。代码的可读性和可维护性直线上升一个复杂的嵌套查询可能只需要一行清晰的路径表达式。更重要的是它让数据处理逻辑与数据结构解耦。只要JSON的总体 schema 不变即使内部某些节点的位置调整了你的查询语句很可能无需修改。在数据抓取、API测试、日志分析、配置管理这些日常开发场景里JSONPath能帮你省下大量繁琐的代码。比如从一堆杂乱的服务器日志JSON中快速过滤出所有状态码为500的错误信息或者从一个复杂的电商API返回结果里一次性提取出所有在售商品的SKU和库存。它不是一个复杂的重型工具而是一个能让你处理JSON时“事半功倍”的利器。2. JSONPath语法精讲从根节点到模糊匹配理解JSONPath首先要把它想象成在JSON这棵“树”上导航。它有一套简洁但功能强大的语法核心是路径表达式。下面我们拆开揉碎了讲。2.1 基本运算符与节点选择JSONPath表达式总是以特定的符号开头指明查询的起点。$ 代表根节点。绝大多数查询都从这里开始。例如$.store.book表示从根节点找到store对象再找到其下的book数组。 代表当前节点。这个符号主要在过滤表达式中使用表示正在被判断的那个节点本身。路径通过点号.或方括号[]来连接。点号表示法. 用于访问对象的子节点键名需是有效的标识符不能以数字开头不含特殊字符。$.store.book是标准用法。方括号表示法[] 功能更强大是“瑞士军刀”。访问数组索引$.store.book[0]获取第一本书。访问对象键名尤其当键名包含特殊字符时$[‘store’][‘book’]等价于$.store.book。如果键名是‘my-key’或‘123abc’则必须使用方括号$[‘my-key’]。切片操作和Python列表切片类似。$.store.book[0:2]获取前两本书索引0和1。也支持步长$.store.book[::2]获取所有偶数索引的书。通配符* 匹配所有元素。$.store.book[*].title可以获取所有书的标题无论book数组里有多少项。递归下降.. 这是一个杀手级特性。它允许你在当前节点及其所有后代节点中搜索无视层级。比如你想找到整个JSON中所有名为price的字段直接用$..price即可。这在处理深度不确定或结构多变的数据时极其有用。2.2 过滤表达式实现条件查询方括号的另一个核心作用是包裹过滤表达式格式为?(.key operator value)。这让你能进行条件筛选。?() 表示这是一个过滤表达式。 代表当前正在被过滤的节点。运算符 支持常见的比较运算符如等于、!不等于、、、、。也支持逻辑运算符与、||或。举个例子假设我们有如下JSON{ “store”: { “book”: [ { “category”: “reference”, “author”: “Nigel Rees”, “title”: “Sayings of the Century”, “price”: 8.95 }, { “category”: “fiction”, “author”: “Evelyn Waugh”, “title”: “Sword of Honour”, “price”: 12.99 }, { “category”: “fiction”, “author”: “Herman Melville”, “title”: “Moby Dick”, “price”: 8.99, “isbn”: “0-553-21311-3” }, { “category”: “fiction”, “author”: “J. R. R. Tolkien”, “title”: “The Lord of the Rings”, “price”: 22.99 } ] } }$.store.book[?(.price 10)] 找出所有价格低于10的书。$.store.book[?(.category ‘fiction’ .price 10)] 找出类别为“fiction”且价格高于10的书。$..book[?(.isbn)] 使用递归下降找到所有包含isbn字段的书即第三本书。注意过滤表达式中的值如果是字符串必须用单引号或双引号括起来。数字和布尔值则不用。2.3 常用表达式速查与对比为了更直观我把常用表达式和它们的含义整理成下表表达式含义示例针对上述JSON$根节点整个JSON文档$.store.book根节点下的store对象中的book数组整个书籍列表$.store.book[0]book数组的第一个元素第一本书Nigel Rees著$.store.book[-1]book数组的最后一个元素最后一本书J.R.R. Tolkien著$.store.book[0,1]book数组的第1和第2个元素前两本书$.store.book[0:2]book数组的切片索引0到1前两本书$.store.book[*]book数组的所有元素所有书$..price递归查找所有price字段[8.95, 12.99, 8.99, 22.99]$.store.book[*].title所有书的title字段[“Sayings…”, “Sword…”, “Moby Dick”, “The Lord…”]$.store.book[?(.price 10)]过滤出价格10的书第一本和第三本$..book[?(.isbn)]递归查找有isbn字段的书第三本书3. 在Python中实战jsonpath-ngvsjsonpath库选型Python社区有几个JSONPath实现最主流的是jsonpath-ng和jsonpath。选择哪一个我的建议是无脑选jsonpath-ng。jsonpath-ng功能更完整完全实现了JSONPath标准对过滤表达式、递归下降等高级特性支持得更好语法也更严谨。而jsonpath库相对老旧一些边缘用例支持可能有问题。在稳定性要求高的生产环境jsonpath-ng是更可靠的选择。安装非常简单pip install jsonpath-ng3.1 基础解析提取与遍历让我们用代码实际操作一下上面的例子。首先解析数据并创建jsonpath_ng的解析器。import json from jsonpath_ng import parse # 示例JSON数据 json_data “”” { “store”: { “book”: [ { “category”: “reference”, “author”: “Nigel Rees”, “title”: “Sayings of the Century”, “price”: 8.95 }, { “category”: “fiction”, “author”: “Evelyn Waugh”, “title”: “Sword of Honour”, “price”: 12.99 }, { “category”: “fiction”, “author”: “Herman Melville”, “title”: “Moby Dick”, “price”: 8.99, “isbn”: “0-553-21311-3” }, { “category”: “fiction”, “author”: “J. R. R. Tolkien”, “title”: “The Lord of the Rings”, “price”: 22.99 } ] } } “”” data json.loads(json_data) # 1. 提取所有书名 jsonpath_expr parse(‘$.store.book[*].title’) titles [match.value for match in jsonpath_expr.find(data)] print(“所有书名”, titles) # 输出: [‘Sayings of the Century‘, ‘Sword of Honour‘, ‘Moby Dick‘, ‘The Lord of the Rings‘] # 2. 递归查找所有价格 jsonpath_expr parse(‘$..price’) prices [match.value for match in jsonpath_expr.find(data)] print(“所有价格”, prices) # 输出: [8.95, 12.99, 8.99, 22.99]parse()函数将字符串表达式编译成一个可重用的对象。find()方法在数据中执行查询返回一个DatumInContext对象的列表其中包含了匹配到的值及其在JSON中的完整路径。我们通常用列表推导式直接取出.value。3.2 高级过滤与多条件查询过滤表达式是JSONPath的精华我们来看看在jsonpath-ng里怎么用。# 3. 找出所有价格低于10的书 jsonpath_expr parse(“$.store.book[?(.price 10)]”) cheap_books [match.value for match in jsonpath_expr.find(data)] print(“价格低于10的书”, cheap_books) # 输出: [{‘category‘: ‘reference‘, …}, {‘category‘: ‘fiction‘, …}] (第一本和第三本) # 4. 找出小说类且价格高于10的书 jsonpath_expr parse(“$.store.book[?(.category ‘fiction’ .price 10)]”) expensive_fiction [match.value for match in jsonpath_expr.find(data)] print(“小说类且价格10的书”, expensive_fiction) # 输出: [{‘category‘: ‘fiction‘, ‘author‘: ‘Evelyn Waugh‘, …}, {‘category‘: ‘fiction‘, ‘author‘: ‘J. R. R. Tolkien‘, …}] # 5. 找出有ISBN的书 jsonpath_expr parse(“$..book[?(.isbn)]”) books_with_isbn [match.value for match in jsonpath_expr.find(data)] print(“有ISBN的书”, books_with_isbn) # 输出: [{‘category‘: ‘fiction‘, ‘author‘: ‘Herman Melville‘, …, ‘isbn‘: ‘0-553-21311-3‘}]踩坑提醒在过滤表达式中使用字符串比较时务必确保引号匹配。如果JSON键名或值本身包含单引号在Python字符串里用双引号定义JSONPath表达式会更安全反之亦然。例如parse(‘$.store.book[?(.author \“O\’Reilly\“)]’)。3.3 理解find()的返回值与路径信息find()返回的不是简单值而是一个包含完整上下文的对象这在调试时非常有用。jsonpath_expr parse(‘$.store.book[0].title’) matches jsonpath_expr.find(data) for match in matches: print(“匹配到的值”, match.value) # ‘Sayings of the Century‘ print(“值的完整路径”, match.full_path) # 这是一个路径对象不是字符串 print(“路径的字符串表示”, str(match.full_path)) # ‘$.store.book[0].title‘ print(“访问路径的各个部分”, match.full_path.left) # 可以用于更复杂的路径操作知道完整路径意味着即使你通过一个很宽的查询如$..price拿到了一堆值你也能精确地定位到每一个值来自哪里。这在处理复杂、异构的数据源时是救命稻草。4. 真实场景下的避坑指南与性能优化纸上谈兵终觉浅在实际项目中使用JSONPath你会遇到一些标准教程里不会提的坑。4.1 当JSONPath查询返回空列表时这是最常见的问题。别急着怀疑人生按这个顺序排查检查数据源首先确认你的data变量确实是Python字典/列表而不是还是JSON字符串。用print(type(data))看一眼。检查路径大小写和拼写JSON是大小写敏感的。$.Store.Book和$.store.book是天壤之别。检查路径是否存在对于可能不存在的路径查询会返回空列表。这是正常行为不是错误。在逻辑上这应该被视为“未找到”而不是“出错”。验证JSONPath表达式语法特别是过滤表达式中的括号、引号和运算符。一个快速验证的方法是先用一个最简单的表达式如$或$.known_key测试是否能返回数据再逐步复杂化你的表达式。注意转义字符如果你的键名包含点号.或星号*等特殊字符在点号表示法中会出问题。必须使用方括号表示法并将其引起来。例如对于键“my.key”应该用$[‘my.key’]而不是$.my.key后者会被解析为访问my对象的key属性。4.2 处理非标准JSON与性能考量JSONPath期望输入是标准的Python数据结构由json.loads()产生。但有时你会遇到一些“类JSON”的数据比如Python中的defaultdict、自定义对象等。jsonpath-ng可能无法直接处理。一个稳妥的做法是在查询前先通过json.dumps()和json.loads()将其“净化”为标准结构。虽然多了一步但避免了难以预料的错误。关于性能需要建立两个认知对于中小型数据几百KB到几MBJSONPath的解析开销微乎其微性能瓶颈通常在IO读取文件或网络请求。放心用。对于超大型JSON几十MB以上或超深嵌套频繁执行复杂的JSONPath查询特别是包含递归下降..的可能会成为瓶颈。因为每次find()都可能需要遍历整个或大部分数据结构。优化建议缓存编译后的表达式parse()有一定开销。如果同一个表达式要执行成千上万次例如在循环中处理大量数据项一定要在循环外部先parse()好。# 好表达式只编译一次 price_expr parse(‘$..price’) for data_chunk in large_data_stream: prices [m.value for m in price_expr.find(data_chunk)] # … 处理 prices # 差每次循环都重新编译表达式性能低下 for data_chunk in large_data_stream: jsonpath_expr parse(‘$..price’) # 不要这样做 prices [m.value for m in jsonpath_expr.find(data_chunk)]精确查询避免过度使用..递归下降非常方便但代价是全局扫描。如果知道目标数据的大致位置尽量使用精确路径。$.store.book[*].price通常比$..price更快。考虑替代方案如果数据极大且查询模式固定可以考虑使用专门的流式JSON解析器如ijson或将其导入到数据库如SQLite中进行SQL查询。但对于绝大多数应用场景jsonpath-ng的性能完全足够。4.3 与类型检查工具如Pydantic的配合在现代Python项目中我们常用Pydantic这类库来定义数据模型并进行验证。JSONPath可以和它们很好地协作。典型的流程是用JSONPath从原始、可能杂乱的数据中提取出目标片段然后将这个片段传递给Pydantic模型进行解析和验证。这样既享受了JSONPath查询的灵活性又获得了强类型检查和数据清洗的安全性。from pydantic import BaseModel from typing import List class BookModel(BaseModel): title: str author: str price: float # 用JSONPath提取原始数据 jsonpath_expr parse(‘$.store.book[*]’) raw_books [match.value for match in jsonpath_expr.find(data)] # 用Pydantic批量验证并转换为对象列表 validated_books [BookModel(**book) for book in raw_books] for book in validated_books: print(f”书名{book.title}, 作者{book.author}“)这种组合拳让你在处理外部API数据或配置文件时游刃有余。5. 超越基础动态路径构建与复杂数据重塑当你真正把JSONPath用起来就会遇到一些更高级的需求。5.1 动态构建查询路径很多时候查询路径不是硬编码的而是需要根据变量动态生成。比如根据用户输入的不同字段名进行查询。def query_by_field(data: dict, field_name: str, min_value: float): “””根据字段名和最小值查询书籍””” # 安全地构建JSONPath表达式 # 注意这里直接将用户输入的field_name拼接进字符串存在注入风险见下文。 # 更安全的做法是使用参数化但jsonpath-ng标准语法不支持。 # 对于可信环境或经过严格清洗的输入可以这样用。 expression f“$.store.book[?(.{field_name} {min_value})]” jsonpath_expr parse(expression) return [match.value for match in jsonpath_expr.find(data)] # 使用示例 result query_by_field(data, ‘price’, 15) print(“价格大于15的书”, result)重要安全警告上面的例子将用户输入的field_name直接拼接进表达式字符串这存在类似SQL注入的“JSONPath注入”风险。如果field_name来自不可信源如网页表单恶意用户可能输入price] | some_malicious_function()之类的字符串来破坏查询或执行意外操作。在安全要求高的场景必须对输入进行严格的白名单校验只允许预定义的、安全的字段名。5.2 处理查询结果中的路径信息进行数据重塑有时你不仅需要值还需要知道这个值来自哪里以便重新组织数据。# 假设我们想得到一个字典{‘书名’: ‘价格’} jsonpath_expr_title parse(‘$..book[*].title’) jsonpath_expr_price parse(‘$..book[*].price’) titles [match for match in jsonpath_expr_title.find(data)] # 保留完整match对象 prices [match for match in jsonpath_expr_price.find(data)] # 假设title和price按顺序一一对应在标准数组结构中成立 book_price_dict {} for title_match, price_match in zip(titles, prices): # 这里只是简单组合更复杂的场景可以利用 match.full_path book_price_dict[title_match.value] price_match.value print(“书价字典”, book_price_dict) # 输出{‘Sayings of the Century‘: 8.95, ‘Sword of Honour‘: 12.99, …}对于更复杂的结构你可能需要编写一个函数根据match.full_path来重建数据的子集或新结构。5.3 调试技巧当查询不如预期时复杂的JSONPath表达式写错了调试起来可能有点痛苦。我的方法是“分而治之”从根开始先执行parse(‘$’).find(data)确保你能访问到数据。逐步深入一层层添加路径。比如目标是$.a.b.c[?(.d 1)]先试$.a再试$.a.b再试$.a.b.c最后加上过滤条件。这样能快速定位到哪一层出了问题。打印中间结果在构建动态表达式时先把生成的表达式字符串打印出来肉眼检查一下。使用在线验证工具有一些在线的JSONPath测试器你可以把样本JSON和表达式贴进去快速验证。这是初期学习语法和调试的利器。JSONPath不是一个庞然大物但它精准地解决了JSON数据查询中的痛点。从繁琐的逐层访问中解放出来用声明式的查询语言去思考“我想要什么”这不仅能提升代码效率更能提升你处理数据时的思维层次。下次再面对一团复杂的JSON时别急着写循环先想想“能不能用JSONPath一行搞定”

相关新闻

零代码AI开发:DeepSeek与Cursor实战千问API设计

零代码AI开发:DeepSeek与Cursor实战千问API设计

1. 项目概述:零代码AI开发实战这个项目展示了如何利用DeepSeek、Cursor、Devbox和Sealos四大工具链,在不编写代码的情况下完成一个完整的AI应用开发和部署流程。作为系列的第二部分,我们将重点探讨接口设计环节,特别是针对千问&am…

2026/8/8 16:45:20 阅读更多 →
基于具身智能体与专用分割模型的细粒度车辆损伤评估技术实践

基于具身智能体与专用分割模型的细粒度车辆损伤评估技术实践

在实际车辆定损、保险理赔和二手车评估场景中,传统的人工目视检查或基于规则的系统难以对车辆损伤进行快速、客观、细粒度的量化评估。近年来,视觉语言模型(VLMs)在理解和生成图像描述方面展现出强大能力,但将其直接应…

2026/8/8 14:05:38 阅读更多 →
本地大语言模型基准测试实战:用Homebench量化评估LLM性能

本地大语言模型基准测试实战:用Homebench量化评估LLM性能

大家好,我是专注于AI工程化实践的技术博主。在本地部署和测试大语言模型(LLM)时,你是否也遇到过这些困扰:模型推理速度慢得让人失去耐心?显存(VRAM)或内存(RAM&#xff0…

2026/8/8 9:43:40 阅读更多 →

最新新闻

无刷电机驱动电路全解析:从分立元件到FOC矢量控制的五种实用方案

无刷电机驱动电路全解析:从分立元件到FOC矢量控制的五种实用方案

1. 项目概述:从“会转”到“转得好”的驱动艺术 搞过机器人、无人机或者自制小电器的朋友,对无刷马达肯定不陌生。这玩意儿效率高、寿命长、扭矩特性好,早就成了各种移动平台和精密设备的心脏。但心脏有了,怎么让它听话地跳动&…

2026/8/8 16:44:54 阅读更多 →
大数运算核心原理与实现:从溢出问题到高精度计算实战

大数运算核心原理与实现:从溢出问题到高精度计算实战

1. 项目概述:当数字溢出你的“内存” 做开发的朋友,尤其是搞算法、密码学或者金融计算的,肯定都遇到过这个场景:你信心满满地写了个程序,输入两个看起来不大的数字,比如 12345678901234567890 和 987654…

2026/8/8 16:44:54 阅读更多 →
如何用cirdit_multimodal_compile_3to5qubit_v1.1实现高效量子电路编译?完整入门指南

如何用cirdit_multimodal_compile_3to5qubit_v1.1实现高效量子电路编译?完整入门指南

如何快速搭建Neo开发环境:5分钟完成本地测试网络部署 【免费下载链接】neo 项目地址: https://gitcode.com/gh_mirrors/an/antshares 想要开始Neo区块链开发却不知从何下手?这篇完整指南将带你5分钟完成Neo开发环境搭建,快速部署本地…

2026/8/8 16:44:54 阅读更多 →
基于FPGA的Game Boy Color硬件复刻:从原理到实践的完整指南

基于FPGA的Game Boy Color硬件复刻:从原理到实践的完整指南

如果你是一位硬件爱好者,或者对复古游戏机改造感兴趣,最近可能被一个词刷屏了: FPGA 。它不再是实验室里高不可攀的芯片,而是正在成为复古硬件复刻和模拟的“终极武器”。今天我们要聊的,就是一个极具代表性的项目—…

2026/8/8 16:43:53 阅读更多 →
免费获取高分辨率转录图谱:ProCapNet本地部署与批量处理教程

免费获取高分辨率转录图谱:ProCapNet本地部署与批量处理教程

LBRY Desktop开发者指南:如何从源码构建和贡献开源项目 【免费下载链接】lbry-desktop A browser and wallet for LBRY, the decentralized, user-controlled content marketplace. 项目地址: https://gitcode.com/gh_mirrors/lb/lbry-desktop LBRY Desktop是…

2026/8/8 16:43:53 阅读更多 →
Python多任务并行处理实战:线程、进程与协程性能优化指南

Python多任务并行处理实战:线程、进程与协程性能优化指南

大家好,我是专注于技术实战分享的博主。在开发后台服务、数据处理脚本或自动化工具时,你是否遇到过这样的场景:需要处理成百上千个独立的任务,比如批量调用API、处理大量文件、或对数据库进行并行查询。如果使用简单的单线程或循环…

2026/8/8 16:43:53 阅读更多 →

日新闻

AI多智能体时代来临,读懂MCP与A2A架构,抢占企业数字化新风口

AI多智能体时代来临,读懂MCP与A2A架构,抢占企业数字化新风口

当下AI应用飞速普及,无数企业下场搭建智能体系统,可落地阶段难题接踵而至:上下文无限堆积频繁爆栈、AI工具调用准确率低下、Token成本居高不下、企业数据权限混乱暗藏安全隐患……很多团队卡在架构搭建环节,空有前沿技术概念&…

2026/8/8 0:00:07 阅读更多 →
PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码

PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码

PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码 【免费下载链接】php-qrcode A PHP QR Code generator and reader with a user-friendly API. 项目地址: https://gitcode.com/gh_mirrors/ph/php-qrcode 在当今数字时代,二维码已…

2026/8/8 0:00:08 阅读更多 →
UniApp微信小程序隐私保护组件开发:从原理到实战

UniApp微信小程序隐私保护组件开发:从原理到实战

1. 项目缘起:为什么我们需要一个隐私保护通用组件?最近在维护一个基于uniapp开发的微信小程序矩阵时,我遇到了一个非常棘手的问题。随着平台对用户隐私保护的要求越来越严格,几乎每一个新版本发布,或者在某些特定机型&…

2026/8/8 0:00:08 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/6 22:02:27 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/8 8:58:26 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/7 23:24:08 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/7 17:02:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/7 23:54:54 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/7 17:02:36 阅读更多 →