1. 程式人生 > >使用 JSONPath 解析 JSON 完整內容詳解

使用 JSONPath 解析 JSON 完整內容詳解

jsonpath的介紹:

JsonPath是一種簡單的方法來提取給定JSON文件的部分內容。 JsonPath有許多程式語言,如Javascript,Python和PHP,Java。

JsonPath提供的json解析非常強大,它提供了類似正則表示式的語法,基本上可以滿足所有你想要獲得的json內容。

 

github上有它的應用:https://github.com/json-path/JsonPath

 

JsonPath可在Central Maven儲存庫中找到。 Maven使用者將其新增到您的POM:

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

 

JsonPath表示式總是以與XPath表示式結合使用XML文件相同的方式引用JSON結構。

JsonPath中的“根成員物件”始終稱為$,無論是物件還是陣列。

JsonPath表示式可以使用點表示法

$.store.book [0].title

或括號表示法

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

 

jsonpath操作符:

操作 說明
$ 查詢根元素。這將啟動所有路徑表示式。
@ 當前節點由過濾謂詞處理。
* 萬用字元,必要時可用任何地方的名稱或數字。
.. 深層掃描。 必要時在任何地方可以使用名稱。
.<name>
點,表示子節點
['<name>' (, '<name>')]
括號表示子項
[<number> (, <number>)]
陣列索引或索引
[start:end]
陣列切片操作
[?(<expression>)] 過濾表示式。 表示式必須求值為一個布林值。

 

 

函式

函式可以在路徑的尾部呼叫,函式的輸出是路徑表示式的輸出,該函式的輸出是由函式本身所決定的。

函式 描述 輸出
min() 提供數字陣列的最小值 Double
max() 提供數字陣列的最大值 Double
avg() 提供數字陣列的平均值 Double
stddev() 提供數字陣列的標準偏差值 Double
length() 提供陣列的長度 Integer

過濾器運算子

過濾器是用於篩選陣列的邏輯表示式。一個典型的過濾器將是[?(@.age > 18)],其中@表示正在處理的當前專案。 可以使用邏輯運算子&&和||建立更復雜的過濾器。 字串文字必須用單引號或雙引號括起來([?(@.color == 'blue')] 或者 [?(@.color == "blue")]).

操作符 描述
== left等於right(注意1不等於'1')
!= 不等於
< 小於
<= 小於等於
> 大於
>= 大於等於
=~ 匹配正則表示式[?(@.name =~ /foo.*?/i)]
in 左邊存在於右邊 [?(@.size in ['S', 'M'])]
nin 左邊不存在於右邊
size (陣列或字串)長度
empty (陣列或字串)為空

接下來我們就用java程式碼來寫一個案例:

Java操作示例

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
        }
    },
    "expensive": 10
}
JsonPath (點選連結測試) 結果
$.store.book[*].author 獲取json中store下book下的所有author值
$..author 獲取所有json中所有author的值
$.store.* 所有的東西,書籍和自行車
$.store..price 獲取json中store下所有price的值
$..book[2] 獲取json中book陣列的第3個值
$..book[-2] 倒數的第二本書
$..book[0,1] 前兩本書
$..book[:2] 從索引0(包括)到索引2(排除)的所有圖書
$..book[1:2] 從索引1(包括)到索引2(排除)的所有圖書
$..book[-2:] 獲取json中book陣列的最後兩個值
$..book[2:] 獲取json中book陣列的第3個到最後一個的區間值
$..book[?(@.isbn)] 獲取json中book陣列中包含isbn的所有值
$.store.book[?(@.price < 10)] 獲取json中book陣列中price<10的所有值
$..book[?(@.price <= $['expensive'])] 獲取json中book陣列中price<=expensive的所有值
$..book[?(@.author =~ /.*REES/i)] 獲取json中book陣列中的作者以REES結尾的所有值(REES不區分大小寫)
$..* 逐層列出json中的所有值,層級由外到內
$..book.length() 獲取json中book陣列的長度

 

上面的json字串的讀取案例:

(1)

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

(2)

如果你只想讀取一次,那麼上面的程式碼就可以了

如果你還想讀取其他路徑,現在上面不是很好的方法,因為他每次獲取都需要再解析整個文件。所以,我們可以先解析整個文件,再選擇呼叫路徑。

String json = "...";
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);

String author0 = JsonPath.read(document, "$.store.book[0].author");
String author1 = JsonPath.read(document, "$.store.book[1].author");

(3)

當在java中使用JsonPath時,重要的是要知道你在結果中期望什麼型別。 JsonPath將自動嘗試將結果轉換為呼叫者預期的型別。

// 丟擲 java.lang.ClassCastException 異常
List<String> list = JsonPath.parse(json).read("$.store.book[0].author")

// 正常
String author = JsonPath.parse(json).read("$.store.book[0].author")

(4)

預設情況下,MappingProvider SPI提供了一個簡單的物件對映器。 這允許您指定所需的返回型別,MappingProvider將嘗試執行對映。 在下面的示例中,演示了Long和Date之間的對映。

String json = "{\"date_as_long\" : 1411455611975}";
Date date = JsonPath.parse(json).read("$['date_as_long']", Date.class);

(5)

如果您將JsonPath配置為使用JacksonMappingProvider或GsonMappingProvider,您甚至可以將JsonPath輸出直接對映到POJO中。

Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class);

 

 

 

另外一個案例:

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

private static void jsonPathTest() {

    JSONObject json = jsonTest();//呼叫自定義的jsonTest()方法獲得json物件,生成上面的json

    //輸出book[0]的author值

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

    //輸出全部author的值,使用Iterator迭代

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

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

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

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

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

    //輸出book[*]中含有isbn元素的book

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

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

    List<Double> prices = JsonPath.read(json, "$..price");

    //可以提前編輯一個路徑,並多次使用它

    JsonPath path = JsonPath.compile("$.store.book[*]");

    List<Object> books = path.read(json);

}

 

 

裝載於:http://www.ibloger.net/article/2329.html,更加詳細的內容請看這篇文章。