Jayway JSONPath 对象和数组表达

问题描述 投票:0回答:3

如果父元素可以是 JSONArray 以及 JSONObject,那么我很难检索值。为此,我使用 Deepcopy 语法来检索它。现在的问题是,如果内部数组中也存在子属性,则我会获取附加值。

例如: Jpath表达式:

$.store..book..innerBook..category

结果是:

[
   "innerReference1",
   "innerBook1Ref1",
   "innerReference2"
]

示例 1 预期结果是:

[
   "innerReference1",
   "innerReference2"
]

示例1:

{
    "store": {
        "book": [
        {
                "innerBook": [
                    {
                        "category": "innerReference1",
                        "author": "Nigel Rees",
                        "innerBook1": [
                            {
                                "category": "innerBook1Ref1"
                            }
                        ]
                    },
                    {
                        "category": "innerReference2",
                        "author": "Nigel Rees"
                    }
                ]
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    },
    "expensive": 10
}

示例2:

{
    "store": {
        "book": [
        {
                "innerBook": 
                    {
                        "category": "innerReference1",
                        "author": "Nigel Rees",
                        "innerBook1": [
                            {
                                "category": "innerBook1Ref1"
                            }
                        ]
                    }
                
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    },
    "expensive": 10
}

示例 2 预期结果是:

[
   "innerReference1"
]
java json jsonpath json-path-expression jayway
3个回答
1
投票

但是有点晚了,我们不需要在

..
之后使用递归下降
innerBook
来遍历数组中的项目;对于 Jayway,我们可以使用
innerBook[*].category
来检索所需的结果,例如 1:

$.store..book..innerBook[*].category

示例 2 需要删除数组访问器:

$.store..book..innerBook.category 

您不能将

innerBook
作为一个 JSON 中的数组和对象,因为它无效。

如果您有一个 API(或类似的),它使用数组或对象类型的

innerbook
属性来提供 JSON(这将是一个设计糟糕的 API,因为 API 的全部目的就是获得预期的响应),您可以同时查询路径或根据
innerBook1
的存在进行类别的访问:

$.store.book..innerBook[?(@.innerBook1)]..category

仅返回两个示例

[
   "innerReference1",
   "innerBook1Ref1"
]

在线尝试这里


0
投票

也许下面是一个更简单的例子。

[
  {
    "title": "The Doe",
    "author": {
      "name": "John Doe"
    }
  },
  {
    "title": "The Does",
    "author": [
      {
        "name": "John Doe"
      },
      {
        "name": "Jane Doe"
      }
    ]
  }
]

我相信我们正在寻找的 JSON 路径可以返回所有作者的姓名。


0
投票

JSONPath 似乎无法在对象和数组上使用相同的表达式返回预期结果。您可以尝试另一个 JSON 库Josson,因为它使用相同的表达式处理对象和数组。

https://github.com/octomix/josson

示例1

Josson ex1 = Josson.fromJsonString(
    "{" +
    "    \"store\": {" +
    "        \"book\": [" +
    "        {" +
    "                \"innerBook\": [" +
    "                    {" +
    "                        \"category\": \"innerReference1\"," +
    "                        \"author\": \"Nigel Rees\"," +
    "                        \"innerBook1\": [" +
    "                            {" +
    "                                \"category\": \"innerBook1Ref1\"" +
    "                            }" +
    "                        ]" +
    "                    }," +
    "                    {" +
    "                        \"category\": \"innerReference2\"," +
    "                        \"author\": \"Nigel Rees\"" +
    "                    }" +
    "                ]" +
    "            }" +
    "        ]," +
    "        \"bicycle\": {" +
    "            \"color\": \"red\"," +
    "            \"price\": 19.95" +
    "        }" +
    "    }," +
    "    \"expensive\": 10" +
    "}");

查询

JsonNode node = ex1.getNode("store.book.innerBook.category");
System.out.println(node.toPrettyString());
//Output: [ "innerReference1", "innerReference2" ]

示例2

Josson ex2 = Josson.fromJsonString(
    "{" +
    "    \"store\": {" +
    "        \"book\": [" +
    "        {" +
    "                \"innerBook\": " +
    "                    {" +
    "                        \"category\": \"innerReference1\"," +
    "                        \"author\": \"Nigel Rees\"," +
    "                        \"innerBook1\": [" +
    "                            {" +
    "                                \"category\": \"innerBook1Ref1\"" +
    "                            }" +
    "                        ]" +
    "                    }" +
    "                " +
    "            }" +
    "        ]," +
    "        \"bicycle\": {" +
    "            \"color\": \"red\"," +
    "            \"price\": 19.95" +
    "        }" +
    "    }," +
    "    \"expensive\": 10" +
    "}");

查询

JsonNode node = ex2.getNode("store.book.innerBook.category");
System.out.println(node.toPrettyString());
//Output: [ "innerReference1" ]

示例3

@thalhamm 建议

Josson ex3 = Josson.fromJsonString(
    "[" +
    "  {" +
    "    \"title\": \"The Doe\"," +
    "    \"author\": {" +
    "      \"name\": \"John Doe\"" +
    "    }" +
    "  }," +
    "  {" +
    "    \"title\": \"The Does\"," +
    "    \"author\": [" +
    "      {" +
    "        \"name\": \"John Doe\"" +
    "      }," +
    "      {" +
    "        \"name\": \"Jane Doe\"" +
    "      }" +
    "    ]" +
    "  }" +
    "]");

查询

JsonNode node = ex3.getNode("author.name");
System.out.println(node.toPrettyString());
//Output: [ "John Doe", "John Doe", "Jane Doe" ]
© www.soinside.com 2019 - 2024. All rights reserved.