XML經常被強調的優點是可以使用大量工具來分析,轉換和有選擇地從XML文檔中提取數據。XPath是這些強大的工具之一。
現在是時候想知道,如果需要像XPath4JSON這樣的東西,它可以解決的問題是什么。
- 可以在客戶端上以JSON結構交互式地找到和提取數據,而無需特殊腳本。
- 客戶端請求的JSON數據可以減少到服務器上的相關部分,例如最小化服務器響應的帶寬使用。
如果我們同意,那么從手邊的JSON結構中挑選零件的工具確實有意義,就會出現一些問題。它應該如何完成它的工作?JSONPath表達式如何?
由於JSON是C系列編程語言數據的自然表示,因此特定語言具有訪問JSON結構的本機語法元素的可能性很高。
以下XPath表達式
/store/book[1]/title
看起來像
x.store.book[0].title
要么
x['store']['book'][0]['title']
在Javascript,Python和PHP中使用包含x
JSON結構的變量。在這里我們觀察到,特定語言通常具有內置的基本XPath功能。
有問題的JSONPath工具應該......
- 自然地基於那些語言特征。
- 僅涵蓋XPath 1.0的基本部分。
- 代碼大小和內存消耗都很輕松。
- 運行效率高。
| 2007-08-17 | e2# JSONPath表達式
JSONPath表達式始終引用JSON結構,其方式與XPath表達式與XML文檔結合使用的方式相同。由於JSON結構通常是匿名的,並且不一定具有“根成員對象”,因此JSONPath假定$
分配給外部對象的抽象名稱。
JSONPath表達式可以使用點注釋
$.store.book[0].title
或括號 -注釋
$['store']['book'][0]['title']
輸入路徑。內部或輸出路徑將始終轉換為更一般的括號 -注釋。
JSONPath允許通配符 *用於成員名稱和數組索引。它借用后代從操作者“..” E4X和陣列切片語法提案[start:end:step]
從EcmaScript的4。
底層腳本語言的表達式(<expr>)
可用作顯式名稱或索引的替代,如
$.store.book[(@.length-1)].title
使用符號'@'表示當前對象。過濾器表達式通過語法支持,?(<boolean expr>)
如
$.store.book[?(@.price < 10)].title
以下是JSONPath語法元素與其XPath對應物的完整概述和並排比較。
XPath的 | JSONPath | 描述 |
/ | $ | 根對象/元素 |
。 | @ | 當前的對象/元素 |
/ | 。要么 [] | 兒童經營者 |
.. | N / A | 父運營商 |
// | .. | 遞歸下降。JSONPath借用了E4X的這種語法。 |
* | * | 通配符。所有對象/元素,無論其名稱如何。 |
@ | N / A | 屬性訪問。JSON結構沒有屬性。 |
[] | [] | 下標運算符。XPath使用它來迭代元素集合和謂詞。在Javascript和JSON中,它是本機數組運算符。 |
| | [,] | XPath中的Union運算符導致節點集的組合。JSONPath允許使用備用名稱或數組索引作為集合。 |
N / A | [開始:結束:步驟] | 從ES4借來的數組切片運算符。 |
[] | ?() | 應用過濾器(腳本)表達式。 |
N / A | () | 腳本表達式,使用底層腳本引擎。 |
() | N / A | 在Xpath中分組 |
XPath還有很多東西可以提供(位置修補,不是縮寫語法,運算符和函數),而不是這里列出的。此外,下標運算符在Xpath和JSONPath中的工作方式存在顯着差異。
- XPath表達式中的方括號始終在由前一個路徑片段生成的節點集上運行。指數總是從1開始。
- 使用JSONPath方括號對前一個路徑片段尋址的對象或數組進行操作。指數總是從0開始。
| 2007-08-18 | E3# JSONPath例子
讓我們通過更多示例來練習JSONPath表達式。我們從一個表示書店(原始XML文件)的XML示例之后構建的簡單JSON結構開始。
{ “store”:{ “book”:[ { “category”:“reference”, “author”:“Nigel Rees”, “title”:“世紀的諺語”, “價格”:8.95 }, { “類別”:“小說”, “作者”:“伊夫林沃”, “標題”:“榮譽之劍”, “價格”:12.99 }, { “類別”:“小說”, “作者”:“Herman Melville”, “title”:“Moby Dick”, “isbn”:“0-553-21311-3”, “price”:8.99 }, { “類別”:“小說”, “作者”:“JRR托爾金”, “標題”:“指環王”, “isbn”:“0-395-19395-8”, “價格”:22.99 } ] “自行車”:{ “顏色”:“紅色”, “價格”:19.95 } } }
XPath的 | JSONPath | 結果 |
/store/book/author |
$.store.book[*].author |
商店里所有書籍的作者 |
//author |
$..author |
所有作者 |
/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[isbn] |
$..book[?(@.isbn)] |
用isbn number過濾所有書籍 |
//book[price<10] |
$..book[?(@.price<10)] |
過濾所有便宜10以上的書籍 |
//* |
$..* |
XML文檔中的所有元素。JSON結構的所有成員。 |
| 2007-08-22 | e4# JSONPath實現
JSONPath在Javascript中實現,用於客戶端使用並移植到PHP以便在服務器上使用。
用法
您需要做的就是下載其中一個文件
將它包含在您的程序中並使用由單個函數組成的簡單API。
jsonPath(obj, expr [, args])
參數:
-
obj (object|array)
: - 表示JSON結構的對象。
-
expr (string)
: - JSONPath表達式字符串。
-
args (object|undefined)
: - 對象控制路徑評估和輸出。目前只支持一個成員。
-
args.resultType ("VALUE"|"PATH")
: - 導致結果為匹配值 (默認值) 或規范化路徑表達式。
返回值:
-
(array|false)
: -
包含與輸入路徑表達式匹配的值或規范化路徑表達式的數組,可用於延遲求值。
false
如果不匹配。
Javascript示例:
VAR O = { /*...*/ }, //在'存儲'從上面JSON對象 RES1 = jsonPath(鄰,“$ ..作者”).toJSONString(), res2 = jsonPath(o,“$ .. author”,{resultType:“PATH” })。toJSONString();
PHP示例:
我們首先需要將JSON字符串轉換為PHP數組。我正在使用Michal Migurski的JSON解析器。
require_once('json.php'); // JSON解析器 require_once('jsonpath.php'); // JSONPath評估程序 $ json = '{...}' ; //來自上面的JSON結構 $ 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);
結果
兩者的Javascript和PHP示例結果在下面的JSON陣列(字符串):
RES1: [ “Nigel Rees”, “Evelyn Waugh”, “Herman Melville”, “JRR Tolkien” ] RES2: [ “$ ['store'] ['book'] [0] ['author']”, “$ ['store'] ['book'] [1] ['author']”, “$ ['store ''['book'] [2] ['author']“, ”$ ['store'] ['book'] [3] ['author']“ ]
請注意,返回值jsonPath
是一個數組,它也是一個有效的JSON結構。因此,您可能希望再次應用於jsonPath
生成的結構,或者使用您喜歡的數組方法之一sort
。
| 2007-08-24 | e5# 問題
- 目前,JSONPath表達式中只允許使用單引號。
- JSONPath位置內的腳本表達式當前未通過遞歸計算
jsonPath
。只有全局$
和局部@
符號通過簡單的正則表達式進行擴展。 - 在不匹配的情況下
jsonPath
返回的替代方法可能是將來返回空數組。false
英文:http://goessner.net/articles/JsonPath/