json-projection-tool
v1.0.1
Published
JSONPath 投影引擎:查询、字段裁剪、别名、写回原始 JSON
Maintainers
Readme
json-projection-tool
JSONPath 投影引擎 —— 在 JSON 中查字段、裁结构、起别名、改完写回。
npm install json-projection-tool五分钟上手
假设你有这段 JSON:
{
"store": {
"book": [
{ "title": "Dune", "price": 29.9, "author": { "name": "Frank", "email": "[email protected]" } },
{ "title": "Foundation", "price": 15.5, "author": { "name": "Isaac", "email": "[email protected]" } }
]
}
}1. 查询 + 裁剪字段
import { parse, evaluate } from 'json-projection-tool';
const query = parse('$.store.book[*].{title, price}');
const results = evaluate(data, query);
// results[0].value → { title: "Dune", price: 29.9 }
// results[1].value → { title: "Foundation", price: 15.5 }2. 给字段起别名
const query = parse('$.store.book[*].{title as 书名, price as 价格}');
// results[0].value → { 书名: "Dune", 价格: 29.9 }3. 嵌套裁剪
parse('$.store.book[*].{title, author.{name, email}}');
// { title: "Dune", author: { name: "Frank", email: "[email protected]" } }4. 编辑后写回原 JSON
import { writeBack } from 'json-projection-tool';
// 查到第一本书,改价格
const results = evaluate(data, parse('$.store.book[0].{title, price}'));
// 修改值:价格改成 "12元",顺便验证类型变更
const edited = { title: 'Dune', price: '12元' };
const { newRoot, success } = writeBack(data, edited, results[0].backPointer);
// newRoot → 新 JSON,原 JSON 不变
// success → true
// newRoot.store.book[0].price → "12元"(number → string)API 参考
parse(expression: string): QueryExpression
解析表达式字符串为 AST。表达式有误时抛出 ParseError。
$.store.book[*].{title, price}
│ │ └──────────────────┘
│ │ 投影块(projection)
│ └── 标准 JSONPath 段
└── 根evaluate(root: JsonValue, query: QueryExpression, options?: QueryOptions): QueryMatch[]
对 JSON 执行查询,返回匹配结果列表。
interface QueryMatch {
path: string; // 匹配节点的 JSONPath,如 "$.store.book[0]"
value: JsonValue; // 投影后的值(如果指定了投影)
originalValue: JsonValue; // 投影前的原始值
backPointer: BackPointer; // 反向指针,用于写回
warnings: QueryWarning[]; // 语义警告
}options:
| 选项 | 默认值 | 说明 |
|------|--------|------|
| strict | false | true 时字段缺失直接报错 |
| maxResults | Infinity | 限制返回结果数 |
writeBack(originalRoot, newValue, backPointer, strict?): WriteBackResult
将编辑后的值通过反向指针写回原始 JSON。不修改原对象,返回新对象。
interface WriteBackResult {
newRoot: JsonValue; // 写回后的新 JSON
success: boolean; // 是否成功
warnings: QueryWarning[]; // 警告列表
}表达式语法速查
| 表达式 | 说明 |
|--------|------|
| $.store.book.{title,price} | 只取 title 和 price |
| $.store.book.{name,author.{name}} | 嵌套裁剪 |
| $.store.book.{name as 书名} | 字段别名 |
| $.store.book.{*} | 通配符,取所有字段 |
| $.store.book[0].{title} | 数组索引 + 投影 |
| $.store.book[0:3].{title} | 切片 + 投影 |
| $.store.book[*].{title} | 通配符展开 + 投影 |
| $.store.book[?(@.price<10)].{title} | 过滤 + 投影 |
| $..author.{name} | 递归下降 + 投影 |
| $.book.{} | 空投影 → {} |
| {name,price} | 纯投影,等价于 $.{name,price} |
类型变更(写回时任意换类型)
写入时不限制类型,29.9 → "12元"、"Dune" → {en:"Dune",zh:"沙丘"}、{...} → null,全都支持。
不容忍的操作
- ❌ 投影结果中新增/删除数组元素
- ❌ 把投影结果对象整体替换为非对象
- ❌ 投影块后再接路径(如
$.book.{x}.y)
测试页
项目自带一个三栏测试页面,加载示例数据即可体验查询→编辑→写回闭环:
npx serve node_modules/json-projection-tool -p 3000
# 打开 http://localhost:3000/test.htmlLicense
MIT
