Jayway - Json-Path 使用(一)

一、JSONPath使用需要的包

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.4.0</version>
</dependency>

 

二、使用說明

1、JSONPath是xpath在json的應用
2、JSONPath 是參照xpath表達式來解析xml文檔的方式,json數據結構通常是匿名的並且不一定需要有根元素。
3、JSONPath 用一個抽象的名字$來表示最外層對象
4、JSONPath 允許使用通配符 * 表示所以的子元素名和數組索引

 

三、JSONPath表達式語法

JSONPath 表達式可以使用.符號解析Json:.store.book[0].title 或者使用[]符號 ['store']['book'][0]['title']

 

四、測試實例(1)

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
    }
  }
}

首先,讀取json文件,使用commons.io的 FileUtils的readFileToString方法:

String path =System.getProperty("user.dir")+File.separator+"testdata"+File.separator+"test.json";

String jsonString = FileUtils.readFileToString(new File(path),"utf-8");

ReadContext context = JsonPath.parse(json);

其次,輸出book[1]的author值。有兩種方法:

方法一:

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

輸出:Evelyn Waugh

方法二:

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

輸出:Evelyn Waugh

// 輸出book[*]中category == 'reference'的book

List<Object> categorys = context.read("$.store.book[?(@.category == 'reference')]");
for(Object st: categorys){
    System.out.println(st.toString());
}

輸出:{category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95}

// 輸出book[*]中price>10的book

List<Object> prices = context.read("$.store.book[?(@.price>10)]");
for(Object p:prices){
    System.out.println(p.toString());
}

輸出:{category=fiction, author=Evelyn Waugh, title=Sword of Honour, price=12.99, isbn=0-553-21311-3}

// bicycle[*]中含有color元素的bicycle

List<Object> color = context.read("$.store.bicycle[?(@.color)]");
for(Object is :color){
    System.out.println(is.toString());
}
輸出://{color=red, price=19.95}

// 輸出該json中所有price的值

List<Object> pp = context.read("$..price");
for(Object p :pp){
    System.out.println(p.toString());
}

輸出:8.95  12.99   19.95

List<String> authors = context.read("$.store.book[*].author");
for (String str : authors) {
    System.out.println(str);
}

輸出:Nigel Rees Evelyn Waugh

 

五、測試實例(2)

Demo.json

{
  "action": "/interface.service/xxx/queryBlackUserData",
  "all": "1",
  "result": {
    "count": 2,
    "tenant_count": 2,
    "records": [
      {
        "name": "張三",
        "pid": "500234199212121212",
        "mobile": "18623456789",
        "applied_at": "3",
        "confirmed_at": "5",
        "confirm_type": "overdue",
        "loan_type": 1,
        "test": "mytest",
        "all": "2"
      },
      {
        "name": "李四",
        "pid": "500234199299999999",
        "mobile": "13098765432",
        "applied_at": "1",
        "confirmed_at": "",
        "confirm_type": "overdue",
        "loan_type": 3,
        "all": "3"
      },
      {
        "name": "王五",
        "pid": "50023415464654659",
        "mobile": "1706454894",
        "applied_at": "-1",
        "confirmed_at": "",
        "confirm_type": "overdue",
        "loan_type": 3
      }
    ],
    "all": "4"
  },
  "code": 200,
  "subtime": "1480495123550",
  "status": "success",
  "ok": 3
}
public class JsonPathDemo {
    public static void main(String[] args) {
        String json = FileUtils.readFileByLines("demo.json");
        ReadContext context = JsonPath.parse(json);

        //1 返回所有name
        List<String> names = context.read("$.result.records[*].name");
        //["張三","李四","王五"]
        System.out.println(names);

        //2 返回所有數組的值
        List<Map<String, String>> objs = context.read("$.result.records[*]");
        //[{"name":"張三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"},{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3","all":"3"},{"name":"王五","pid":"50023415464654659","mobile":"1706454894","applied_at":"-1","confirmed_at":"","confirm_type":"overdue","loan_type":"3"}]
        System.out.println(objs);

        //3 返回第一個的name
        String name0 = context.read("$.result.records[0].name");
        //張三
        System.out.println(name0);

        //4 返回下標爲0 和 2 的數組值
        List<String> name0and2 = context.read("$.result.records[0,2].name");
        //["張三","王五"]
        System.out.println(name0and2);

        //5 返回下標爲0 到 下標爲1的 的數組值  這裏[0:2] 表示包含0 但是 不包含2
        List<String> name0to2 = context.read("$.result.records[0:2].name");
        //["張三","李四"]
        System.out.println(name0to2);

        //6 返回數組的最後兩個值
        List<String> lastTwoName = context.read("$.result.records[-2:].name");
        //["李四","王五"]
        System.out.println(lastTwoName);

        //7 返回下標爲1之後的所有數組值 [1,...]
        List<String> nameFromOne = context.read("$.result.records[1:].name");
        //["李四","王五"]
        System.out.println(nameFromOne);

        //8 返回下標爲3之前的所有數組值 [0,3)
        List<String> nameEndTwo = context.read("$.result.records[:3].name");
        //["張三","李四","王五"]
        System.out.println(nameEndTwo);

        //9 返回applied_at大於等於2的值
        List<Map<String, String>> records = context.read("$.result.records[?(@.applied_at >= '2')]");
        //[{"name":"張三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"}]
        System.out.println(records);

        //10 返回name等於李四的值
        List<Map<String, String>> records0 = context.read("$.result.records[?(@.name == '李四')]");
        //[{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3"}]
        System.out.println(records0);

        //11 返回有test屬性的數組
        List<Map<String, String>> records1 = context.read("$.result.records[?(@.test)]");
        //[{"name":"張三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"}]
        System.out.println(records1);

        //12 返回有test屬性的數組
        List<String> list = context.read("$..all");
        //["1","4","2","3"]
        System.out.println(list);

        //12 以當前json的某個值爲條件查詢 這裏ok爲1 取出records數組中applied_at等於1的數組
        List<String> ok = context.read("$.result.records[?(@.applied_at == $['ok'])]");
        //["1","4","2","3"]
        System.out.println(ok);

        //13 正則匹配
        List<String> regexName = context.read("$.result.records[?(@.pid =~ /.*999/i)]");
        //[{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3","all":"3"}]
        System.out.println(regexName);

        //14 多條件
        List<String> mobile = context.read("$.result.records[?(@.all == '2' || @.name == '李四' )].mobile");
        //["18623456789","13098765432"]
        System.out.println(mobile);

        //14 查詢數組長度
        Integer length01 = context.read("$.result.records.length()");
        //3
        System.out.println(length01);

        //15 查詢list裏面每個對象長度
        List<Integer> length02 = context.read("$.result.records[?(@.all == '2' || @.name == '李四' )].length()");
        //[9,8]
        System.out.println(length02);

        //16 最大值
        Object maxV = context.read("$.max($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //3.0
        System.out.println(maxV);

        //17 最小值
        Object minV = context.read("$.min($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //1.0
        System.out.println(minV);

        //18 平均值
        double avgV = context.read("$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //2.3333333333333335
        System.out.println(avgV);

        //19 標準差
        double stddevV = context.read("$.stddev($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");
        //0.9428090415820636
        System.out.println(stddevV);

        //20 讀取一個不存在的
        String haha = context.read("$.result.haha");
        //拋出異常
        //Exception in thread "main" com.jayway.jsonpath.PathNotFoundException: No results for path: $['result']['haha']
        //at com.jayway.jsonpath.internal.path.EvaluationContextImpl.getValue(EvaluationContextImpl.java:133)
        //at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
        //at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:102)
        //at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:89)
        //at cn.lijie.jsonpath.JsonPathDemo.main(JsonPathDemo.java:58)
        //at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        //at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        //at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        //at java.lang.reflect.Method.invoke(Method.java:498)
        //at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
        System.out.println(haha);
    }
}

 

六、XPATH 和 JSONPath 獲取元素的方法比較

[]在xpath表達式總是從前面的路徑來操作數組,索引是從1開始。

使用JOSNPath的[]操作符操作一個對象或者數組,索引是從0開始。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章