(另请参阅 开发依赖的许可证)
分析、转换并从 JSON 文档(以及 JavaScript 对象)中选择性地提取数据。
jsonpath-plus 在原始规范的基础上进行了扩展,新增了一些额外的运算符,并明确了原始规范未明确说明的一些行为。
试试浏览器演示或 Runkit (Node)。
请注意:本项目目前没有积极维护。我们可能会接受有良好文档的 PR 或一些简单的更新,但不打算自行修复问题或添加新功能。
^ 用于获取匹配项的父级~ 用于获取匹配项的属性名(以数组形式)@null()、@boolean()、@number()、@string()、@array()、@object()@integer()@scalar()(在查询 JavaScript 对象时,它还接受 undefined 和非有限数字,以及所有基本的非对象/非函数类型)@other() 可与用户定义的 otherTypeCallback 结合使用根据 json-querying-performance-testing,与其他 json 查询库相比,jsonpath-plus 在处理大型和小型数据集时都表现稳定。您可以通过自行运行该项目并添加更多性能测试用例来验证这些发现。
npm install jsonpath-plus
## 设置
### Node.js```js
const {JSONPath} = require('jsonpath-plus');
const result = JSONPath({path: '...', json});
对于浏览器使用,你可以直接包含 dist/index-browser-umd.cjs;无需
任何 Browserify 魔法:```html
### ESM(现代浏览器)
您也可以使用 ES6 模块导入(适用于现代浏览器):```html
<script type="module">
import {
JSONPath
} from './node_modules/jsonpath-plus/dist/index-browser-esm.js';
const result = JSONPath({path: '...', json: {}});
</script>
或者,如果你正在打包你的 JavaScript(例如,使用 Rollup),只需使用,
注意 mainFields
应包含 browser 用于浏览器构建(对于 Node,默认情况下,
检查 module,应该没问题):```js
import {JSONPath} from 'jsonpath-plus';
const result = JSONPath({path: '...', json});
## 用法
可用完整签名如下:```
const result = JSONPath([options,] path, json, callback, otherTypeCallback);
参数 path、json、callback 和 otherTypeCallback
也可以(连同任何其他可用属性)在 options
上表达。
请注意,result 将包含找到的所有项(可选择
包装到数组中),而 callback 可用于在
发现每个项时执行某些操作,
回调函数将根据结果中独立项的数量
执行 0 到 N 次。
有关 JSONPath 可用参数的更多信息,请参阅下面的文档。
另请参阅 API 文档。
可以在 options 对象或 evaluate 方法(作为第一个参数)上提供的属性包括:
false,
则可以手动调用 evaluate 方法。wrap 设置为 false,
且没有找到结果,则将返回 undefined(而当 wrap 设置为 true 时,则返回空数组)。
如果 wrap 设置为 false 且找到单个非数组结果,则只返回该结果
(不在数组中)。不过,如果找到多个结果,仍将返回一个数组。
为避免歧义(在需要区分某个结果是失败还是空数组的情况下),
建议将默认值改为 false。autostart 属性设置为 false 时才需要
此方法。它可用于使用相同配置重复求值。
除了列出的属性外,后一种方法形式可以
接受任何其他允许的实例属性(除了
autostart,因为它在这里没有相关性)。['$', 'aProperty', 'anotherProperty']。$['aProperty']['anotherProperty][0]。JSONPath 的终端
结构 ~ 和 ^ 以及像 @string() 这样的类型运算符会被
静默剥离。/aProperty/anotherProperty/0
(任何内部的 ~ 和 / 字符都按照 JSON 指针规范进行转义)。
JSONPath 的终端结构 ~ 和 ^ 以及
像 @string() 这样的类型运算符会被静默剥离。给定以下 JSON,取自 http://goessner.net/articles/JsonPath/:```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", "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 } } }
以及以下 XML 表示形式:```xml
<store>
<book>
<category>reference</category>
<author>Nigel Rees</author>
<title>Sayings of the Century</title>
<price>8.95</price>
</book>
<book>
<category>fiction</category>
<author>Evelyn Waugh</author>
<title>Sword of Honour</title>
<price>12.99</price>
</book>
<book>
<category>fiction</category>
<author>Herman Melville</author>
<title>Moby Dick</title>
<isbn>0-553-21311-3</isbn>
<price>8.99</price>
</book>
<book>
<category>fiction</category>
<author>J. R. R. Tolkien</author>
<title>The Lord of the Rings</title>
<isbn>0-395-19395-8</isbn>
<price>22.99</price>
</book>
<bicycle>
<color>red</color>
<price>19.95</price>
</bicycle>
</store>
请注意,以下 XPath 示例并不区分
检索元素与其文本内容(除非为了
比较或防止歧义而有必要)。注意:要测试这些 XPath 示例
(包括 2.0 示例),这个演示
可能会有所帮助(设置为 xml 或 xml-strict)。| XPath | JSONPath | 结果 | 说明 |
|-------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| /store/book/author | $.store.book[*].author | store 中所有书籍的作者 | 也可以不带 $. 表示为 store.book[*].author(虽然这并未出现在原始规范中);不过请注意,某些字符字面量($ 和 @)需要转义 |
| //author | $..author | 所有作者 | |
| | | store 中的所有东西,即它的书籍(一个书籍数组)和一辆红色自行车(一个自行车对象) | |
| | | store 中所有东西的价格 | |
| | | 第三本书(书籍对象) | |
| | | 按顺序排列的最后一本书 | 要访问带有特殊字符的属性,请使用 作为过滤器(此特定功能未出现在原始规范中) |
| | | 前两本书 | |
| 或 (在 XPath 2.0 中) | | 所有书籍的类别和作者 | |
| | | 过滤所有带有 ISBN 编号的书籍 | 要访问带有特殊字符的属性,请使用 作为过滤器(此特定功能未出现在原始规范中) |
| | | 过滤所有价格低于 10 的书籍 | |
| | | 获取所有属性为 price 且值不等于 8.95 的对象的所有属性值 | 使用裸 可以按属性值过滤对象(不一定要在数组内),你可以在表达式后添加 来获取拥有被过滤属性的对象 |
| | | JSON 对象的根(即整个对象本身) | 要获取字面量 (单独使用或在路径中的任意位置),必须使用反引号转义 |
| | | XML 文档中根节点下的所有元素(和文本)。JSON 结构中根节点下的所有成员。 | |
| | | XML 文档中的所有元素。JSON 结构中包括根在内的所有父级组件。 | 此行为在原始规范中没有直接规定 |
| | | 价格大于 19 的那些特定项的父级(即 store 值是 bicycle 的父级,book 数组是单本书的父级) | 父级(脱字符)未出现在原始规范中 |
| (在 XPath 2.0 中) | | store 子对象("book" 和 "bicycle")的属性名称。与通配符属性一起使用时很有用。 | 属性名称(波浪号)未出现在原始规范中 |
| (在 XPath 2.0 中) | | 除位于指向第一本书的路径上的那本书之外的所有书籍 | 未出现在原始规范中 |
| | | 获取所有此类书籍的类别:书籍的父对象有一个颜色为红色的 bicycle 子对象(即所有书籍) | 未出现在原始规范中 |
| | | 获取 "book" 的所有子项,但 "category" 类型的子项除外 | 未出现在原始规范中 |
| | | 获取所有属性(由于我们在数组内部进行访问,该属性是数字索引)不为 0 的书籍 | 未出现在原始规范中 |
| | | 获取 store 的孙级节点,这些节点的父级属性不是 book(即 bicycle 的子项:"color" 和 "price") | 未出现在原始规范中 |
| | | 获取所有书籍实例的属性值,其中这些值的父级属性(即保存书籍条目父对象的数组索引)不为 0 | 未出现在原始规范中 |
| | | 过滤所有价格等于第三本书价格的书籍 | 未出现在原始规范中 |
| (在 XPath 2.0 中) | | 获取 book 数组中的数值 | 、其他基本类型(、)、其他底层派生类型(、、)、JSONSchema 新增的类型 、复合类型 (它也接受 和非有限数,适用于 JavaScript 对象以及所有基本的非对象/非函数类型)、需要与用户自定义回调一起使用的类型 (参见 ),以及以下在查询非 JSON JavaScript 对象时仍可与 JSONPath 一起使用的非 JSON 类型(、、)均未出现在原始规范中 |
| (XPath 2.0) | | 匹配正则表达式(以 'TION' 结尾,不区分大小写)的所有书籍类别 | 未出现在原始规范中。 |
| (XPath 2.0) | | 所有拥有匹配正则表达式(以 'TION' 结尾,不区分大小写)的属性的书籍 | 未出现在原始规范中。注意:在表达式末尾使用父级选择器 可返回到父对象;如果没有父级选择器,它将匹配两个 键值。 |
| | (例如, 用于匹配字面名称为 的属性) | 转义其后的整个序列(将其视为字面量) | 未出现在原始规范中;要获取字面量反引号,请使用额外的反引号进行转义 |作为可选的 "sandbox" 对象选项属性提供的任何附加变量,也可用于(基于括号的)求值。
@ 引用其子节点外,实际上还会选择直接子节点;而在 XPath 中,过滤条件不会选择子节点,而是界定结果中将获取其父节点中的哪些节点。提供了一个基本的命令行界面(CLI)。使用 npx jsonpath-plus <json-file> <jsonpath-query> 访问它。
|)以及分组。在 Node 上运行测试:```shell npm test
对于浏览器内测试:
- 提供 js/html 文件:```shell
npm run browser-test
请参阅 SECURITY.md 了解重要的安全注意事项以及如何报告漏洞。
@undefined()@function()@nonFinite()@path/@parent/@property/@parentProperty/@root 简写选择器` 用于转义剩余序列@['...']/?@['...'] 语法用于转义过滤器中属性名内的特殊字符$..(获取所有父级组件)safe:在浏览器中,它将使用一个极简的脚本引擎,该引擎不使用
eval 或 Function,并满足内容安全策略。在 NodeJS 中,
它没有效果,等同于 native,因为在那里脚本是安全的。
native:使用原生脚本能力。即在浏览器中使用不安全的 eval 或
Function,在 nodejs 中使用 vm.Script。false:禁用 JavaScript
求值表达式,并在尝试这些表达式时抛出异常。
callback [ (code, context) => value]:一个自定义实现,调用时以 code 和 context
作为参数,返回求值后的值。
class:一个以 code 作为构造函数参数创建的类,代码通过使用 context
调用 runInNewContext 来求值。
``parentProperty。这可以是字符串
属性名或数字数组索引。resultType)、
有效载荷的类型(是普通的 "value" 还是 "property"
名称),以及完整的有效载荷对象(包含所有 resultType)。@other() 来确定内置类型之外的类型。如果遇到这样的
路径,则将使用项目的值、其路径、其父对象及其父对象的属性名
来调用 otherTypeCallback,
并且它应返回一个布尔值,指示所提供的值
是否属于 "other" 类型(或者它可以处理转换并
返回 false)。/store/*$.store.*/store//price$.store..price//book[3]$..book[2]//book[last()]$..book[(@.length-1)]$..book[-1:][(@['...'])]//book[position()<3]$..book[0,1]$..book[:2]//book/*[self::category\|self::author]//book/(category,author)$..book[0][category,author]//book[isbn]$..book[?(@.isbn)][?@['...']]//book[price<10]$..book[?(@.price<10)]//*[name() = 'price' and . != 8.95]$..*[?(@property === 'price' && @ !== 8.95)]@^/$$//*/*\|//*/*/text()$..*//*$..//*[price>19]/..$..[?(@.price>19)]^/store/*/name()$.store.*~/store/book[not(. is /store/book[1])]$.store.book[?(@path !== "$['store']['book'][0]")]@path//book[parent::*/bicycle/color = "red"]/category$..book[?(@parent.bicycle && @parent.bicycle.color === "red")].category@parent//book/*[name() != 'category']$..book.*[?(@property !== "category")]@property//book[position() != 1]$..book[?(@property !== 0)]@property/store/*/*[name(parent::*) != 'book']$.store.*[?(@parentProperty !== "book")]@parentProperty//book[count(preceding-sibling::*) != 0]/*/text()$..book.*[?(@parentProperty !== 0)]@parentProperty//book[price = /store/book[3]/price]$..book[?(@.price === @root.store.book[2].price)]@root//book/../*[. instance of element(*, xs:decimal)]$..book..*@number()@number()@boolean()@string()@null()@object()@array()@integer()@scalar()undefined@other()otherTypeCallback@undefined()@function()@nonFinite()//book/*[name() = 'category' and matches(., 'tion$')]$..book.*[?(@property === "category" && @.match(/TION$/i))]@property//book/*[matches(name(), 'bn$')]/parent::*$..book.*[?(@property.match(/bn$/i))]^@property^isbn` `$$`