JsonPath详解

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
时间: 2024-10-26 16:11:50

JsonPath详解的相关文章

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

随着RESTful Web Service的流行,测试对外的Service是否满足期望也变的必要的.从Spring 3.2开始Spring了Spring Web测试框架,如果版本低于3.2,请使用spring-test-mvc项目(合并到spring3.2中了). Spring MVC测试框架提供了对服务器端和客户端(基于RestTemplate的客户端)提供了支持. 对于服务器端:在Spring 3.2之前,我们测试时一般都是直接new控制器,注入依赖,然后判断返回值.但是我们无法连同Spri

【Kubernetes】kubectl命令详解 &#646984;

目录 用法概述 子命令详解 参数列表 输出格式 操作示例 原文: http://blog.gqylpy.com/gqy/385 @ 用法概述 kubectl 命令行的语法如下: kubectl [command] [TYPE] [NAME] [flags] command:子命令,用于操作 Kubernetes 集群资源对象的命令,例如 create.delete.describe.get.apply 等. TYPE:资源对象类型,区分大小写,能以单数.复数形式或者简写形式表达. NAME:资源

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

HttpServletResponse和HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20

.NET深入解析LINQ框架(五:IQueryable、IQueryProvider接口详解)

阅读目录: 1.环路执行对象模型.碎片化执行模型(假递归式调用) 2.N层对象执行模型(纵横向对比链式扩展方法) 3.LINQ查询表达式和链式查询方法其实都是空壳子 4.详细的对象结构图(对象的执行原理) 5.IQueryable<T>与IQueryProvider一对一的关系能否改成一对多的关系 6.完整的自定义查询 1]. 环路执行对象模型.碎片化执行模型(假递归式调用) 这个主题扯的可能有点远,但是它关系着整个LINQ框架的设计结构,至少在我还没有搞懂LINQ的本意之前,在我脑海里一直频

netstat状态详解

一.生产服务器netstat tcp连接状态................................................................................ 2 1.1生产服务器某个业务LVS负载均衡上连接状态数量............................................... 2 1.2生产服务器某个业务web上连接状态数量...............................................