Rust JSON路径查询库serde_json_path的使用指南
概述
serde_json_path是一个基于Rust语言的JSON路径查询库,专门用于高效解析和操作JSON数据。它构建在serde_json之上,提供了强大的JSONPath表达式支持,让开发者能够轻松地从复杂的JSON结构中提取和操作数据。
主要特性
- 完整的JSONPath语法支持
- 零拷贝解析和查询
- 类型安全的操作
- 高性能的查询引擎
- 与serde_json无缝集成
安装方法
在Cargo.toml中添加依赖:
[dependencies]
serde_json_path = "0.6"
serde_json = "1.0"
基本使用方法
1. 解析JSON数据
use serde_json::{Value, json};
use serde_json_path::JsonPath;
fn main() {
let json_data = json!({
"store": {
"book": [
{
"title": "Rust编程",
"price": 45.99
},
{
"title": "JSON指南",
"price": 29.99
}
]
}
});
// 创建JSONPath查询
let path = JsonPath::parse("$.store.book[*].title").unwrap();
// 执行查询
let results = path.query(&json_data).all();
for result in results {
println!("找到标题: {}", result);
}
}
2. 复杂查询示例
use serde_json_path::JsonPath;
fn complex_query() {
let json_data = serde_json::from_str(r#"
{
"users": [
{
"id": 1,
"name": "Alice",
"age": 30,
"active": true
},
{
"id": 2,
"name": "Bob",
"age": 25,
"active": false
}
]
}
"#).unwrap();
// 查询所有活跃用户的名称
let path = JsonPath::parse("$.users[?(@.active == true)].name").unwrap();
let active_users = path.query(&json_data).all();
println!("活跃用户: {:?}", active_users);
}
3. 使用过滤器
use serde_json_path::JsonPath;
fn filter_example() {
let data = json!({
"products": [
{"name": "Laptop", "price": 1200, "stock": 5},
{"name": "Mouse", "price": 25, "stock": 0},
{"name": "Keyboard", "price": 75, "stock": 10}
]
});
// 查询有库存且价格低于100的商品
let path = JsonPath::parse("$.products[?(@.stock > 0 && @.price < 100)]").unwrap();
let available_products = path.query(&data).all();
println!("可用商品: {:?}", available_products);
}
高级功能
1. 多结果查询
use serde_json_path::JsonPath;
fn multi_result_query() {
let data = json!({
"departments": {
"engineering": {
"employees": ["Alice", "Bob", "Charlie"]
},
"marketing": {
"employees": ["David", "Eve"]
}
}
});
let path = JsonPath::parse("$..employees[*]").unwrap();
let all_employees = path.query(&data).all();
println!("所有员工: {:?}", all_employees);
}
2. 修改查询结果
use serde_json_path::JsonPath;
fn modify_data() {
let mut data = json!({
"settings": {
"theme": "light",
"notifications": true
}
});
let path = JsonPath::parse("$.settings.theme").unwrap();
if let Some(value) = path.query(&data).first() {
if let Some(theme) = value.as_str() {
println!("当前主题: {}", theme);
}
}
}
性能提示
- 对于重复查询,建议预先编译JSONPath表达式
- 使用
query().first()
当只需要第一个匹配结果时
- 避免在循环中重复解析相同的JSONPath表达式
错误处理
use serde_json_path::{JsonPath, ParseError};
fn safe_query() -> Result<(), ParseError> {
let path = JsonPath::parse("$.invalid.path[?(@.value)]")?;
// 处理查询...
Ok(())
}
serde_json_path库为Rust开发者提供了强大而高效的JSON数据处理能力,特别适合处理复杂的JSON结构和需要高性能查询的场景。
完整示例demo
use serde_json::{json, Value};
use serde_json_path::{JsonPath, ParseError};
fn main() -> Result<(), ParseError> {
// 示例1: 基本JSON数据查询
println!("=== 基本JSON数据查询示例 ===");
let json_data = json!({
"store": {
"book": [
{
"title": "Rust编程",
"price": 45.99,
"category": "编程"
},
{
"title": "JSON指南",
"price": 29.99,
"category": "技术"
},
{
"title": "数据结构",
"price": 39.99,
"category": "编程"
}
]
}
});
// 查询所有书籍标题
let title_path = JsonPath::parse("$.store.book[*].title")?;
let titles = title_path.query(&json_data).all();
println!("所有书籍标题: {:?}", titles);
// 示例2: 使用过滤器查询
println!("\n=== 过滤器查询示例 ===");
let programming_books_path = JsonPath::parse("$.store.book[?(@.category == '编程')]")?;
let programming_books = programming_books_path.query(&json_data).all();
println!("编程类书籍: {:?}", programming_books);
// 示例3: 价格范围查询
println!("\n=== 价格范围查询示例 ===");
let affordable_books_path = JsonPath::parse("$.store.book[?(@.price < 40)]")?;
let affordable_books = affordable_books_path.query(&json_data).all();
println!("价格低于40的书籍: {:?}", affordable_books);
// 示例4: 复杂嵌套查询
println!("\n=== 复杂嵌套查询示例 ===");
let complex_data = json!({
"company": {
"departments": [
{
"name": "研发部",
"employees": [
{"name": "张三", "age": 28, "skills": ["Rust", "Python"]},
{"name": "李四", "age": 32, "skills": ["Java", "Go"]}
]
},
{
"name": "市场部",
"employees": [
{"name": "王五", "age": 26, "skills": ["营销", "沟通"]},
{"name": "赵六", "age": 29, "skills": ["策划", "设计"]}
]
}
]
}
});
// 查询所有员工姓名
let all_employees_path = JsonPath::parse("$..employees[*].name")?;
let all_employees = all_employees_path.query(&complex_data).all();
println!("所有员工姓名: {:?}", all_employees);
// 查询会Rust的员工
let rust_developers_path = JsonPath::parse("$..employees[?('Rust' in @.skills)]")?;
let rust_developers = rust_developers_path.query(&complex_data).all();
println!("会Rust的员工: {:?}", rust_developers);
// 示例5: 错误处理
println!("\n=== 错误处理示例 ===");
match JsonPath::parse("$.invalid.path[?(@.value)]") {
Ok(path) => {
let results = path.query(&json_data).all();
println!("查询结果: {:?}", results);
}
Err(e) => {
println!("JSONPath解析错误: {}", e);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_json_path_queries() -> Result<(), ParseError> {
let data = json!({
"users": [
{"id": 1, "name": "Alice", "active": true},
{"id": 2, "name": "Bob", "active": false},
{"id": 3, "name": "Charlie", "active": true}
]
});
// 测试活跃用户查询
let active_users_path = JsonPath::parse("$.users[?(@.active == true)].name")?;
let active_users = active_users_path.query(&data).all();
assert_eq!(active_users.len(), 2);
// 测试ID查询
let user_by_id_path = JsonPath::parse("$.users[?(@.id == 2)]")?;
let user = user_by_id_path.query(&data).first();
assert!(user.is_some());
Ok(())
}
}
这个完整的示例演示了serde_json_path库的主要功能,包括基本查询、过滤器使用、复杂嵌套结构查询、错误处理以及单元测试。示例涵盖了实际开发中常见的各种使用场景。