Rust JSON路径处理库serde_json_path_macros的使用,高效解析与操作JSON数据路径
Rust JSON路径处理库serde_json_path_macros的使用,高效解析与操作JSON数据路径
serde_json_path_macros是为serde_json_path crate提供的宏支持。
安装
在项目目录中运行以下Cargo命令:
cargo add serde_json_path_macros
或者在Cargo.toml中添加以下行:
serde_json_path_macros = "0.1.6"
完整示例代码
以下是一个使用serde_json_path_macros处理JSON路径的完整示例:
use serde_json::{json, Value};
use serde_json_path::JsonPath;
use serde_json_path_macros::json_path;
fn main() {
// 创建一个示例JSON数据
let data: 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
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
});
// 使用宏创建JSON路径
let path = json_path!("$.store.book[*].author");
// 执行查询
let authors = path.query(&data).all();
// 输出结果
println!("Authors: {:?}", authors);
// 输出: Authors: ["Nigel Rees", "Evelyn Waugh"]
// 另一个示例 - 获取所有价格
let prices_path = json_path!("$..price");
let prices = prices_path.query(&data).all();
println!("Prices: {:?}", prices);
// 输出: Prices: [8.95, 12.99, 19.95]
// 使用条件过滤
let expensive_books = json_path!("$.store.book[?(@.price > 10)]")
.query(&data)
.all();
println!("Expensive books: {:?}", expensive_books);
// 输出: Expensive books: [{"category": "fiction", "author": "Evelyn Waugh", ...}]
}
主要功能
- 使用
json_path!
宏创建JSON路径表达式 - 支持标准JSONPath语法:
$
表示根对象.
或[]
用于子节点访问*
通配符匹配所有元素..
递归下降?(<expression>)
过滤表达式
完整示例demo
基于上述内容,这里提供一个更完整的示例代码,展示更多JSON路径操作:
use serde_json::{json, Value};
use serde_json_path::JsonPath;
use serde_json_path_macros::json_path;
fn main() {
// 创建更复杂的JSON数据结构
let data: Value = json!({
"employees": [
{
"id": 1,
"name": "John",
"department": "IT",
"skills": ["Rust", "Python", "Java"],
"salary": 85000,
"contact": {
"email": "john@example.com",
"phone": "123-456-7890"
}
},
{
"id": 2,
"name": "Alice",
"department": "HR",
"skills": ["Communication", "Recruiting"],
"salary": 75000,
"contact": {
"email": "alice@example.com",
"phone": "234-567-8901"
}
},
{
"id": 3,
"name": "Bob",
"department": "IT",
"skills": ["JavaScript", "TypeScript", "React"],
"salary": 90000,
"contact": {
"email": "bob@example.com",
"phone": "345-678-9012"
}
}
],
"company": {
"name": "Tech Corp",
"location": "New York",
"founded": 2010
}
});
// 示例1:获取所有员工姓名
let names_path = json_path!("$.employees[*].name");
let names = names_path.query(&data).all();
println!("所有员工姓名: {:?}", names);
// 示例2:获取IT部门员工
let it_employees = json_path!("$.employees[?(@.department == 'IT')]")
.query(&data)
.all();
println!("IT部门员工: {:?}", it_employees);
// 示例3:获取高薪员工(工资>80000)的邮箱
let high_salary_emails = json_path!("$.employees[?(@.salary > 80000)].contact.email")
.query(&data)
.all();
println!("高薪员工邮箱: {:?}", high_salary_emails);
// 示例4:获取所有技能(递归查找)
let all_skills = json_path!("$..skills[*]")
.query(&data)
.all();
println!("所有技能: {:?}", all_skills);
// 示例5:使用多重条件查询
let it_high_salary = json_path!("$.employees[?(@.department == 'IT' && @.salary > 85000)]")
.query(&data)
.all();
println!("IT部门高薪员工: {:?}", it_high_salary);
}
这个完整示例展示了:
- 基本路径查询
- 条件过滤
- 递归查找
- 多重条件组合查询
- 嵌套对象访问
通过这些示例,可以全面了解如何使用serde_json_path_macros库来高效地处理和操作JSON数据。
1 回复
Rust JSON路径处理库serde_json_path_macros使用指南
概述
serde_json_path_macros
是一个基于serde_json
和jsonpath_lib
的Rust宏库,提供了简洁高效的JSON路径查询和操作功能。它允许你使用类似JavaScript的语法来查询和修改JSON数据。
主要特性
- 简洁的宏语法进行JSON路径查询
- 支持创建、读取、更新和删除操作
- 编译时检查路径表达式
- 高性能的JSON数据处理
安装
在Cargo.toml
中添加依赖:
[dependencies]
serde_json = "1.0"
serde_json_path_macros = "0.1"
基本使用方法
1. 简单查询
use serde_json::{json, Value};
use serde_json_path_macros::json_path;
fn main() {
let data = json!({
"store": {
"book": [
{ "title": "Rust Programming", "price": 35.99 },
{ "title": "JSON Path Guide", "price": 29.99 }
],
"bicycle": { "color": "red", "price": 399.99 }
}
});
// 查询所有书籍标题
let titles = json_path!(data, "$.store.book[*].title");
println!("Book titles: {:?}", titles);
// 查询价格低于100的所有物品
let cheap_items = json_path!(data, "$..*[?(@.price < 100)]");
println!("Cheap items: {:?}", cheap_items);
}
2. 修改JSON数据
use serde_json::{json, Value};
use serde_json_path_macros::json_path_mut;
fn main() {
let mut data = json!({
"users": [
{ "id": 1, "name": "Alice", "active": false },
{ "id": 2, "name": "Bob", "active": true }
]
});
// 激活所有用户
json_path_mut!(data, "$.users[*].active").set(true);
println!("Updated data: {}", data);
}
3. 删除元素
use serde_json::{json, Value};
use serde_json_path_macros::json_path_mut;
fn main() {
let mut data = json!({
"products": [
{ "id": "p1", "stock": 0 },
{ "id": "p2", "stock": 42 },
{ "id": "p3", "stock": 0 }
]
});
// 删除库存为0的产品
json_path_mut!(data, "$.products[?(@.stock == 0)]").remove();
println!("Filtered products: {}", data);
}
高级用法
1. 链式操作
use serde_json::{json, Value};
use serde_json_path_macros::{json_path, json_path_mut};
fn main() {
let mut data = json!({
"departments": {
"engineering": {
"employees": [
{ "name": "Alice", "salary": 80000 },
{ "name": "Bob", "salary": 75000 }
]
},
"marketing": {
"employees": [
{ "name": "Charlie", "salary": 70000 }
]
}
}
});
// 给所有工程师加薪10%
json_path_mut!(data, "$.departments.engineering.employees[*].salary")
.update(|salary: &mut f64| *salary *= 1.1);
// 查询所有员工姓名
let names = json_path!(data, "$..employees[*].name");
println!("All employee names: {:?}", names);
}
2. 使用变量构建路径
use serde_json::{json, Value};
use serde_json_path_macros::json_path;
fn main() {
let data = json!({
"users": {
"123": { "name": "Alice", "role": "admin" },
"456": { "name": "Bob", "role": "user" }
}
});
let user_id = "123";
let path = format!("$.users.{}", user_id);
// 注意:这种情况下需要使用jsonpath_lib直接操作
let user = jsonpath_lib::select(&data, &path).unwrap();
println!("User {}: {:?}", user_id, user);
}
性能提示
- 对于频繁的JSON操作,考虑将JSON解析为
serde_json::Value
后重复使用 - 复杂的路径查询可能影响性能,尽量简化路径表达式
- 批量操作比多次单独操作更高效
注意事项
- 路径表达式在编译时检查,错误的语法会导致编译错误
- 修改操作需要可变引用,确保数据是可变的
- 对于非常大的JSON文档,考虑使用流式解析器替代
这个库为Rust中的JSON处理提供了强大而灵活的工具,特别适合需要复杂JSON操作的场景。
完整示例代码
// 完整示例:使用serde_json_path_macros进行复杂JSON操作
use serde_json::{json, Value};
use serde_json_path_macros::{json_path, json_path_mut};
fn main() {
// 1. 创建复杂JSON数据结构
let mut company_data = json!({
"company": {
"name": "Tech Corp",
"departments": {
"engineering": {
"team": "Rust",
"members": [
{"id": 1, "name": "Alice", "skills": ["Rust", "C++"], "salary": 90000},
{"id": 2, "name": "Bob", "skills": ["Rust", "Python"], "salary": 85000}
]
},
"design": {
"team": "UI/UX",
"members": [
{"id": 3, "name": "Charlie", "skills": ["Figma", "Photoshop"], "salary": 75000}
]
}
},
"projects": [
{"id": "p1", "name": "Rust Microservices", "status": "active"},
{"id": "p2", "name": "Web Redesign", "status": "pending"}
]
}
});
// 2. 查询操作示例
// 查询所有工程师姓名
let engineer_names = json_path!(company_data, "$.company.departments.engineering.members[*].name");
println!("Engineer names: {:?}", engineer_names);
// 查询所有活跃项目
let active_projects = json_path!(company_data, "$.company.projects[?(@.status == 'active')]");
println!("Active projects: {:?}", active_projects);
// 3. 修改操作示例
// 给所有工程师加薪5%
json_path_mut!(company_data, "$.company.departments.engineering.members[*].salary")
.update(|salary: &mut f64| *salary *= 1.05);
// 激活所有pending状态的项目
json_path_mut!(company_data, "$.company.projects[?(@.status == 'pending')].status")
.set("active");
// 4. 删除操作示例
// 删除技能中不包含Rust的工程师
json_path_mut!(company_data, "$.company.departments.engineering.members[?(!@.skills.contains('Rust'))]")
.remove();
// 5. 最终数据输出
println!("Final company data:\n{}", company_data);
// 6. 使用变量构建路径查询
let project_id = "p1";
let project_path = format!("$.company.projects[?(@.id == '{}')]", project_id);
let project = jsonpath_lib::select(&company_data, &project_path).unwrap();
println!("Project {} details: {:?}", project_id, project);
}
这个完整示例展示了:
- 创建复杂的嵌套JSON数据结构
- 使用各种查询方式获取数据
- 对数据进行修改和更新
- 根据条件删除数据元素
- 使用变量构建动态路径查询
运行此代码前请确保已正确添加依赖项。这个示例综合展示了serde_json_path_macros
在实际应用中的强大功能。