コンセプト
JSONPath には、一致またはフィルタリングの目的で式に任意の Javascript を挿入できるフィルター構文があるようです。@
また、現在のノードのショートカットとしても使用されます。これら 2 つのことを組み合わせた例は次のようになります。
$..book[?(@.price<10)] // 10 より安いすべての本をフィルタリングします
したがって、これはおそらくここで使用したいものです。
解決
考えていたクエリをテストするために、 JSONPath のリポジトリにあるjsonpath-test-js.htmlファイルを変更してデータをテストしました。サンプルをコピーして HTML ファイルに貼り付け、ブラウザにロードするだけです。
o
彼らのテスト スイートには、および と呼ばれるフィールドを持つオブジェクトの配列がありますp
。o
には操作対象の元のデータが含まれ、p
には適用する JSONPath 式の配列が含まれますo
。これらすべてのペアをループし、すべてp
の をそれぞれo
の に適用して、結果を出力します。単純な REPL ほど便利ではありませんが、それで十分です。
これが私が思いついたものです:
<html>
<head>
<title> JSONPath - Tests (js)</title>
<script type="text/javascript" src="http://www.json.org/json.js"></script>
<script type="text/javascript"
src="http://jsonpath.googlecode.com/svn/trunk/src/js/jsonpath.js">
</script>
</head>
<body>
<pre>
<script type="text/javascript">
var out = "", tests =
[ { "o": { "results" : { "div" : [ { "clazz": "sylEntry",
"id": "sylOne", "div": [ { "clazz": "sT", "id": "sOT",
"p": "Mon 11/17, Computer work time" }, { "clazz": "des",
"id": "dOne", "p": "All classes Siebel 0218" } ] } ] } },
"p": ["$.results..div[?(@.clazz=='sT')].p", // my suggestion expression
"$.results..div[*].p"]}, // your question's expression
];
function evaluate($, p) {
var res = eval(p);
return res != null ? res.toJSONString() : null;
}
for (var i=0; i<tests.length; i++) {
var pathes;
for (var j=0; j<tests[i].p.length; j++) {
pre = ">";
if (pathes = jsonPath(tests[i].o, tests[i].p[j], {resultType: "PATH"}))
for (var k=0; k<pathes.length; k++) {
out += pre + " " + pathes[k] +
" = " + evaluate(tests[i].o, pathes[k]) + "\n";
pre = " ";
}
}
out += "<hr/>";
}
document.write(out);
</script>
</pre>
</body>
</html>
これにより、最初にクエリ式の結果が出力され、次にあなたの結果が出力されることに注意してください。これにより、それらが生成するものを比較できます。
これが生成する出力は次のとおりです。
> $['results']['div'][0]['div'][0]['p'] = "Mon 11/17, Computer work time"
> $['results']['div'][0]['div'][0]['p'] = "Mon 11/17, Computer work time"
$['results']['div'][0]['div'][4]['p'] = "All classes Siebel 0218"
したがって、フィルター式の正しい演算子は です==
。つまり、正しい式は次のとおりです。
$.results..div[?(@.class=='sT')].p
ただし、残念な問題が 1 つ見つかりました (少なくとも JSONPath の Javascript 実装で): 上記のクエリで「クラス」という単語を使用すると、次のようになります。
SyntaxError: jsonPath: Parse error: _v.class=='sT'
私の唯一の推測はeval
、JSONPath 式を実際に評価するためにどこかで呼び出されているということです。class
は Javascript の予約語であるため、問題が発生しています。の代替構文を使用してみましょう@.class
:
$.results..div[?(@.['class']=='sT')].p
結果:
> $['results']['div'][0]['div'][0]['p'] = "Mon 11/17, Computer work time"
> $['results']['div'][0]['div'][0]['p'] = "Mon 11/17, Computer work time"
$['results']['div'][0]['div'][5]['p'] = "All classes Siebel 0218"
したがって、上記の表現を使用すると、準備完了です。フィルター機能は強力に見えるので、その機能を試してみる価値は十分にあるでしょう!