代码之家  ›  专栏  ›  技术社区  ›  Alex

创建一个jsonpath表达式,以便它只检索一个特定的值?

  •  3
  • Alex  · 技术社区  · 14 年前

    我有一些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" 带有类的DIV元素的内容 "sT" . 我想使用一个循环并执行如下操作:

    var arrayOfResults = $.results..div.p 
    

    不起作用,因为我只想用类检索DIV元素的p值 “ST” .

    那么,如何构造我的jsonpath,以便它检索包含在divs类“st”中的p元素数组。

    谢谢!!

    3 回复  |  直到 8 年前
        1
  •  10
  •   jasonmp85    14 年前

    概念

    jsonpath显然有一个过滤器语法,允许您将任意的javascript插入到表达式中,以便进行匹配或过滤。它也使用 @ 作为当前节点的快捷方式。 Their example 把这两件事结合起来,就像这样:

    $..书?(@.Price<10)]//全部过滤 10本以下的书

    所以这可能是你想在这里使用的。

    解决方案

    为了测试我想到的查询,我修改了 jsonpath-test-js.html 文件在 JSONPath's repo 测试你的数据。您可以复制粘贴我的样本到一个HTML文件,然后将其加载到浏览器中。

    他们的测试套件有一个对象数组,其中的字段名为 o p . o 包含要在其上操作的原始数据 包含要应用于的jsonpath表达式数组 o . 它循环所有这些对,并应用所有 S到他们各自的 o s,打印出结果。没有简单的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
    

    但是,我发现了一个不幸的问题(至少在jsonpath的javascript实现中):在上面的查询中使用“class”一词会导致:

    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"
    

    所以用上面的表达,你应该走得好!过滤器功能看起来很强大,所以很可能值得探索它的功能!

        2
  •  1
  •   Hakan Bilgin    11 年前

    您可以使用defiantjs,而不是使用难以掌握的非标准查询样式。( http://defiantjs.com ,它使用“search”方法扩展了全局对象JSON,您可以使用标准化的xpath查询来查询JSON结构。此方法返回数组中的匹配项(如果未找到匹配项,则返回空数组)。

    下面是下面代码的一个工作JSodle;
    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

        3
  •  0
  •   Jayen Chondigara    8 年前

    试试这个

    jsonpath.with(jsonResponse.param(“name”,“get name”).get(“findall a->a.name==name”)。