3

以下が小さなサンプルであるJSONがいくつかあります。

{
    "results": {
        "div": [
            {
                "class": "sylEntry",
                "div": [
                    {
                        "class": "sT",
                        "id": "sOT",
                        "p": "Mon 11/17, Computer work time"
                    },
                    {
                        "class": "des",
                        "id": "dOne",
                        "p": "All classes Siebel 0218"
                    }
                ],
                "id": "sylOne"
            }
        ]
    }
}

"p"class を持つ div 要素のコンテンツのみを取得したいと思います"sT"。ループを使用して、次のようなことをしたいと思います。

var arrayOfResults = $.results..div.p 

class を持つ div 要素の p 値のみを取得したいため、機能しません"sT"

では、div クラス "sT" に含まれる p 要素の配列を取得するように JSONpath を構築するにはどうすればよいでしょうか。

ありがとう!!

4

3 に答える 3

10

コンセプト

JSONPath には、一致またはフィルタリングの目的で式に任意の Javascript を挿入できるフィルター構文があるようです。@また、現在のノードのショートカットとしても使用されます。これら 2 つのことを組み合わせた例は次のようになります。

$..book[?(@.price<10)] // 10 より安いすべての本をフィルタリングします

したがって、これはおそらくここで使用したいものです。

解決

考えていたクエリをテストするために、 JSONPath のリポジトリにあるjsonpath-test-js.htmlファイルを変更してデータをテストしました。サンプルをコピーして HTML ファイルに貼り付け、ブラウザにロードするだけです。

o彼らのテスト スイートには、および と呼ばれるフィールドを持つオブジェクトの配列がありますpoには操作対象の元のデータが含まれ、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"

したがって、上記の表現を使用すると、準備完了です。フィルター機能は強力に見えるので、その機能を試してみる価値は十分にあるでしょう!

于 2010-05-28T23:58:19.550 に答える
1

把握しにくい非標準のクエリ スタイルを使用する代わりに、グローバル オブジェクト JSON を「検索」メソッドで拡張する DefiantJS ( http://defiantjs.com ) を使用できます。このメソッドを使用すると、JSON 構造をクエリできます。標準化された XPath クエリ。このメソッドは、一致を配列で返します (一致が見つからない場合は空の配列)。

これは、以下のコードの動作する JSfiddle です。
http://jsfiddle.net/hbi99/sy2bb/

var data = {
       "results": {
          "div": {
             "class": "sylEntry",
             "id": "sylOne",
             "div": [
                {
                   "class": "sT",
                   "id": "sOT",
                   "p": "Mon 11/17, Computer work time"
                },
                {
                   "class": "des",
                   "id": "dOne",
                   "p": "All classes Siebel 0218"
                }
             ]
          }
       }
    },
    res = JSON.search( data, '//div[class="sT"]/p' );

console.log( res[0] );
// Mon 11/17, Computer work time

XPath とその仕組みについて理解するには、この XPath エバリュエーター ツール (
http://defiantjs.com/#xpath_evaluator ) を確認してください。

于 2014-01-14T17:14:06.327 に答える