Rust JSON路径查询库serde_json_path的使用,高效解析和操作JSON数据的强大工具

serde_json_path

serde_json_path 允许你使用 JSONPath(RFC 9535)来查询 serde_json::Value 类型。

Build status Crates.io Documentation CTS Submodule Update and Test

了解更多

  • 查看 Crate 文档以获取使用方法和示例。
  • 查看 JSONPath 标准(RFC 9535)以获取有关 JSONPath 查询语法及其使用示例的更多详细信息。
  • 在沙盒中尝试

许可证

该项目根据 MIT 许可证进行许可。

贡献

除非你明确声明,否则任何有意提交包含在 serde_json_path 中的贡献,都将以 MIT 许可证进行许可,无需任何附加条款或条件。

内容中提供的示例:

// 示例代码将在完整示例中提供

完整示例代码:

use serde_json::Value;
use serde_json_path::JsonPath;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 示例 JSON 数据
    let json_data = r#"
    {
        "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",
                    "isbn": "0-553-21311-3",
                    "price": 8.99
                },
                {
                    "category": "fiction",
                    "author": "J. R. R. Tolkien",
                    "title": "The Lord of the Rings",
                    "isbn": "0-395-19395-8",
                    "price": 22.99
                }
            ],
            "bicycle": {
                "color": "red",
                "price": 19.95
            }
        }
    }"#;

    // 解析 JSON 数据
    let value: Value = serde_json::from_str(json_data)?;

    // 创建 JSONPath 查询
    let path = JsonPath::parse("$.store.book[*].author")?;

    // 执行查询
    let authors = path.query(&value).all();

    // 输出结果
    println!("Authors:");
    for author in authors {
        println!("  {}", author);
    }

    // 另一个查询示例:查找所有价格低于 10 的书籍
    let cheap_books_path = JsonPath::parse("$.store.book[?(@.price < 10)]")?;
    let cheap_books = cheap_books_path.query(&value).all();

    println!("\nBooks under $10:");
    for book in cheap_books {
        println!("  {}: ${}", book["title"], book["price"]);
    }

    Ok(())
}

1 回复

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库的主要功能,包括基本查询、过滤器使用、复杂嵌套结构查询、错误处理以及单元测试。示例涵盖了实际开发中常见的各种使用场景。

回到顶部