JsonPath is to JSON what XPATH is to XML, a simple way to extract parts of a given document. JsonPath is available in many programming languages such as Javascript, Python and PHP. Now also in Java!
News
 
2013-09-27 Released 0.9.0 bug fixes, general improvements
 
2012-04-16 Released 0.8.1 bug fixes, improved docs, general improvements
 
2012-03-08 Released 0.8.0 bug fixes, Filter builder, Json model, POJO mapping (optional) and compliance improvements.
 
2012-02-09 Released 0.5.6 including bug fixes and performance improvements.
Given
 
{ "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,
        "isbn": "0-553-21311-3"
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
 
Read
 
All authors:
 
List<String> authors = JsonPath.read(json, "$.store.book[*].author");
 
Author of first book in store:
 
String author = JsonPath.read(json, "$.store.book[1].author");
 
All books with category = "reference"
 
List<Object> books = JsonPath.read(json, "$.store.book[?(@.category == 'reference')]");
 
List<Object> books = JsonPath.read(json, "$.store.book[?]", filter(where("category").is("reference")));
 
All books that cost more than 10 USD
 
List<Object> books = JsonPath.read(json, "$.store.book[?(@.price > 10)]");
 
List<Object> books = JsonPath.read(json, "$.store.book[?]", filter(where("price").gt(10)));
 
All books that have isbn
 
List<Object> books = JsonPath.read(json, "$.store.book[?(@.isbn)]");
 
List<Object> books = JsonPath.read(json, "$.store.book[?]", filter(where("isbn").exists(true)));
 
Chained filters
 
Filter filter = Filter.filter(Criteria.where("isbn").exists(true).and("category").in("fiction", "reference"))
 
List<Object> books = JsonPath.read(json, "$.store.book[?]", filter);
 
Custom filters
 
Filter myFilter = new Filter.FilterAdapter<Map<String, Object>>(){
                @Override
                public boolean accept(Map<String, Object> map) {
                     return map.containsKey("isbn");  
                }
            };
 
List<Object> books = JsonPath.read(json, "$.store.book[?]", myFilter);
 
All prices in the document
 
List<Double> prices = JsonPath.read(json, "$..price");
 
Compiled path
 
You can pre compile a path and use it multiple times
 
JsonPath path = JsonPath.compile("$.store.book[*]");
 
List<Object> books = path.read(json);
 
Assert
 
Asserts are made with Hamcrest matchers
 
JsonAssert.with(json).assertThat("$.store.bicycle.color", Matchers.equalTo("red"))
          .assertThat("$.store.bicycle.price", Matchers.equalTo(19.95D));
 
Add some static imports and you get this
 
with(json).assertThat("$.store.bicycle.color", equalTo("red"))
          .assertThat("$.store.bicycle.price", equalTo(19.95D));
 
The Hamcrest library contains a lot of different matchers and they can often be nested.
 
with(json).assertThat("$..author", hasItems("Nigel Rees", "Evelyn Waugh"))
          .assertThat("$..author", is(collectionWithSize(equalTo(2))));
 
with(json).assertThat("$.store.book[?(@.category == 'x')]", emptyCollection());
 
If you don't find the matcher you need, roll your own.
Download
 
Json-path is available at Maven Central
 
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>0.9.1</version>
</dependency>
 
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path-assert</artifactId>
    <version>0.9.1</version>
    <scope>test</scope>
</dependency>

# JSONPath - XPath for JSON

A frequently emphasized advantage of XML is the availability of plenty tools to analyse, transform and selectively extract data out of XML documents. XPath is one of these powerful tools.

It's time to wonder, if there is a need for something like XPath4JSON and what are the problems it can solve.

  • Data may be interactively found and extracted out of JSON structures on the client without special scripting.
  • JSON data requested by the client can be reduced to the relevant parts on the server, such minimizing the bandwidth usage of the server response.

If we agree, that a tool for picking parts out of a JSON structure at hand does make sense, some questions come up. How should it do its job? How do JSONPath expressions look like?

Due to the fact, that JSON is a natural representation of data for the C family of programming languages, the chances are high, that the particular language has native syntax elements to access a JSON structure.

The following XPath expression

/store/book[1]/title

would look like

x.store.book[0].title

or

x['store']['book'][0]['title']

in Javascript, Python and PHP with a variable x holding the JSON structure. Here we observe, that the particular language usually has a fundamental XPath feature already built in.

The JSONPath tool in question should …

  • be naturally based on those language characteristics.
  • cover only essential parts of XPath 1.0.
  • be lightweight in code size and memory consumption.
  • be runtime efficient.

|2007-08-17| e2# JSONPath expressions

JSONPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination with an XML document. Since a JSON structure is usually anonymous and doesn't necessarily have a "root member object" JSONPath assumes the abstract name $ assigned to the outer level object.

JSONPath expressions can use the dot–notation

$.store.book[0].title

or the bracket–notation

$['store']['book'][0]['title']

for input pathes. Internal or output pathes will always be converted to the more general bracket–notation.

JSONPath allows the wildcard symbol * for member names and array indices. It borrows thedescendant operator '..' from E4X and the array slice syntax proposal [start:end:step] fromECMASCRIPT 4.

Expressions of the underlying scripting language (<expr>) can be used as an alternative to explicit names or indices as in

$.store.book[(@.length-1)].title

using the symbol '@' for the current object. Filter expressions are supported via the syntax ?(<boolean expr>) as in

$.store.book[?(@.price < 10)].title

Here is a complete overview and a side by side comparison of the JSONPath syntax elements with its XPath counterparts.

XPath JSONPath Description
/ $ the root object/element
. @ the current object/element
/ . or [] child operator
.. n/a parent operator
// .. recursive descent. JSONPath borrows this syntax from E4X.
* * wildcard. All objects/elements regardless their names.
@ n/a attribute access. JSON structures don't have attributes.
[] [] subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator.
| [,] Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set.
n/a [start:end:step] array slice operator borrowed from ES4.
[] ?() applies a filter (script) expression.
n/a () script expression, using the underlying script engine.
() n/a grouping in Xpath

XPath has a lot more to offer (Location pathes in not abbreviated syntax, operators and functions) than listed here. Moreover there is a remarkable difference how the subscript operator works in Xpath and JSONPath.

  • Square brackets in XPath expressions always operate on the node set resulting from the previous path fragment. Indices always start by 1.
  • With JSONPath square brackets operate on the object or array addressed by the previous path fragment. Indices always start by 0.

|2007-08-18| e3# JSONPath examples

Let's practice JSONPath expressions by some more examples. We start with a simple JSON structure built after an XML example representing a bookstore (original XML file).

{ "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
    }
  }
}
XPath JSONPath Result
/store/book/author $.store.book[*].author the authors of all books in the store
//author $..author all authors
/store/* $.store.* all things in store, which are some books and a red bicycle.
/store//price $.store..price the price of everything in the store.
//book[3] $..book[2] the third book
//book[last()] $..book[(@.length-1)]
$..book[-1:]
the last book in order.
//book[position()<3] $..book[0,1]
$..book[:2]
the first two books
//book[isbn] $..book[?(@.isbn)] filter all books with isbn number
//book[price<10] $..book[?(@.price<10)] filter all books cheapier than 10
//* $..* all Elements in XML document. All members of JSON structure.

|2007-08-22| e4# JSONPath implementation

JSONPath is implemented in Javascript for clientside usage and ported over to PHP for use on the server.

Usage

All you need to do is downloading either of the files

include it in your program and use the simple API consisting of one single function.

jsonPath(obj, expr [, args])

parameters:

obj (object|array):
Object representing the JSON structure.
expr (string):
JSONPath expression string.
args (object|undefined):
Object controlling path evaluation and output. Currently only one member is supported.
args.resultType ("VALUE"|"PATH"):
causes the result to be either matching values (default) or normalized path expressions.

return value:

(array|false):
Array holding either values or normalized path expressions matching the input path expression, which can be used for lazy evaluation. false in case of no match.

Javascript Example:

var o = { /*...*/ },  // the 'store' JSON object from above
    res1 = jsonPath(o, "$..author").toJSONString(),
    res2 = jsonPath(o, "$..author", {resultType:"PATH"}).toJSONString();

PHP example:

We need here to convert the JSON string to a PHP array first. I am using Michal Migurski's JSON parser for that.

require_once('json.php');      // JSON parser
require_once('jsonpath.php');  // JSONPath evaluator

$json = '{ ... }';  // JSON structure from above

$parser = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
$o = $parser->decode($json);
$match1 = jsonPath($o, "$..author");
$match2 = jsonPath($o, "$..author", array("resultType" => "PATH"));
$res1 = $parser->encode($match1);
$res2 = $parser->encode($match2);

results

Both Javascript and PHP example result in the following JSON arrays (as strings):

res1:
[ "Nigel Rees",
  "Evelyn Waugh",
  "Herman Melville",
  "J. R. R. Tolkien"
]
res2:
[ "$['store']['book'][0]['author']",
  "$['store']['book'][1]['author']",
  "$['store']['book'][2]['author']",
  "$['store']['book'][3]['author']"
]

Please note, that the return value of jsonPath is an array, which is also a valid JSON structure. So you might want to apply jsonPath to the resulting structure again or use one of your favorite array methods as sort with it.

|2007-08-24| e5# Issues

  • Currently only single quotes allowed inside of JSONPath expressions.
  • Script expressions inside of JSONPath locations are currently not recursively evaluated byjsonPath. Only the global $ and local @ symbols are expanded by a simple regular expression.
  • An alternative for jsonPath to return false in case of no match may be to return an empty array in future.

JSON 信息抽取类库:JsonPath

JsonPath 对于 JSON 来说相当于 XPATH 对于 XML。这是一个简单的从文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Java, Python 和 PHP。

给定以下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,
        "isbn": "0-553-21311-3"
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

读取

所有作者:

List<String> authors = JsonPath.read(json, "$.store.book[*].author");

Author of first book in store:

String author = JsonPath.read(json, "$.store.book[1].author");

所有分类="reference"的书籍

List<Object> books = JsonPath.read(json, "$.store.book[?(@.category == 'reference')]");

List<Object> books = JsonPath.read(json, "$.store.book[?]", filter(where("category").is("reference")));

参考:http://goessner.net/articles/JsonPath/http://www.oschina.net/code/snippet_273576_34427https://github.com/jayway/JsonPathhttp://mvnrepository.com/artifact/com.jayway.jsonpath/json-path/2.2.0http://www.oschina.net/p/jsonpath

JsonPath详解的更多相关文章

  1. Kubernetes 实践指南之Kubernetes 的命令行工具详解

    kubectl作为客户端CLI工具,可以让用户通过命令行的方式对Kubernetes集群进行管理.本节内容将对kubectl的子命令和用法进行详细描述. 一.kubectl 用法概述 kubectl语 ...

  2. Spring MVC测试框架详解——服务端测试

    随着RESTful Web Service的流行,测试对外的Service是否满足期望也变的必要的.从Spring 3.2开始Spring了Spring Web测试框架,如果版本低于3.2,请使用sp ...

  3. SpringMvc测试框架详解----服务端测试

    随着RESTful Web Service的流行,测试对外的Service是否满足期望也变的必要的.从Spring 3.2开始Spring了Spring Web测试框架,如果版本低于3.2,请使用sp ...

  4. MockMvc详解

    ★  MockMvc - SpringMVC单元测试的独立测试: 一.简介 为何使用MockMvc?         对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通 ...

  5. Jmeter(十七) - 从入门到精通 - JMeter后置处理器 -上篇(详解教程)

    1.简介 后置处理器是在发出“取样器请求”之后执行一些操作.取样器用来模拟用户请求,有时候服务器的响应数据在后续请求中需要用到,我们的势必要对这些响应数据进行处理,后置处理器就是来完成这项工作的.例如 ...

  6. Kubernetes,kubectl常用命令详解

    kubectl概述 祭出一张图,转载至 kubernetes-handbook/kubectl命令概述 ,可以对命令族有个整体的概念. 环境准备 允许master节点部署pod,使用命令如下: kub ...

  7. 『动善时』JMeter基础 — 30、JMeter中JSON断言详解

    目录 1.JSON断言组件界面详解 2.JSON断言组件的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 (3)JSON断言界面内容 (4)查看运行结果 (5)断言结果组件说明 3.JS ...

  8. istio基础详解

    1.Istio介绍? 官方文档:https://istio.io/docs/concepts/what-is-istio/ 中文官方文档:https://istio.io/zh/docs/concep ...

  9. kubernetes之kubectl与YAML详解1

    k8s集群的日志,带有组件的信息,多看日志. kubectl命令汇总 kubectl命令汇总 kubectl命令帮助信息 [root@mcwk8s04 ~]# kubectl -h kubectl c ...

随机推荐

  1. Node.js 【CORS(cross origin resource sharing) on ExpressJS之笔记】

    app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*" ...

  2. try catch finally 关闭流标准的写法

    平常开发中,都知道要在finlly里关闭流,但是有时finlly里代码不当,会引起另外的异常. 以下是看struts2源代码看到的,随手记录下. 有两点注意: (1)判断流是否为空. (2)filly ...

  3. uniquery 配合 mssql 自带存储过程实现分页

    --使用系统存储过程实现的通用分页存储过程 -- 此过程原作者,应该是:邹健老前辈 CREATE PROC sp_PageView @sql ntext, --要执行的sql语句 , --要显示的页码 ...

  4. Qt 内存管理机制(转)

      许转载http://devbean.blog.51cto.com/448512/526734 强类型语言在创建对象时总会显式或隐式地包含对象的类型信息.也就是说,强类型语言在分配对象内存空间时,总 ...

  5. javaweb 在netbeans 上的部署问题

    最近用netbeans去部署开发 javaweb程序!现总结一下自己的安装开发过程. 第一,在官网上下载netbeans时,有自带的tomcat,可以直接使用这个服务器,在我这儿这个自带的tomcat ...

  6. SYBASE时间计算

    以摘录了计算月初,月末,上月同日,下月同日,上年同日,下年同日(年有闰月问题),各种函数输出格式. 可以写到存储过程中也可单独使用. Sybase日期函数 文章分类:数据库 关键字: sybase日期 ...

  7. 制作输入框(Input)

    怎样判断是否应当使用输入框 输入框,就是用户可以自由输入文本的地方.当需要判断是否需要使用输入框时,可以遵循一条原则:凡是需要用户自主输入文本的地方,几乎都必须使用输入框. 输入框的常见用法:输入登录 ...

  8. dive into python 读笔(2)

    chapter 4 自省, summary: # 用可选和命名参数定义和调用函数 # 用 str 强制转换任意值为字符串形式 # 用 getattr 动态得到函数和其它属性的引用 # 扩展列表解析语法 ...

  9. Interlocked.Increment 方法 和Interlocked.Decrement 方法作用

    Interlocked.Increment 方法:让++成为原子操作:Interlocked.Decrement 方法让--成为原子操作.什么叫原子操作呢.就是不会被别人打断,因为C#中的一个语句,编 ...

  10. SQL的集合运算符介绍

    最近学习了SQL SERVER方面的知识,毕竟做Web应用,少不了跟数据库打交道.学习的来源主要是<程序员的SQL金典>这本书. 今天介绍数据库里面的集合运算符,它是指匹配集合的每一个结果 ...