使用JSONPath解析阵列与非阵列JSON的麻烦

时间:2015-12-22 18:33:36

标签: json jsonpath

我的JSON如下所示。我正在尝试使用JSONPath来获取__ content __值,其中SKU是“8A-OK9F-9LI8”和Component.Type =='Principal'。现在,我正在玩this JSON Path Expression Tester。

此JSONPath表达式获取了我需要的所有组件信息:

$.Order..Fulfillment[?(@.SKU=='8A-OK9F-9LI8')]..Component

但是进一步过滤,例如$.Order..Fulfillment[?(@.SKU=='8A-OK9F-9LI8')]..Component[?(@.Type=='Principal')]只抓取我需要的两个Component元素中的一个(我相信Array one)。我怀疑这是因为一个是一个数组,一个是一个JSON元素。是否可以使用一个命令来获取它,或者我必须组合几个命令(一个用于Array,一个用于单个JSON元素)?如果是这样,我如何获取我目前没有获得的其他组件信息:

$.Order..Fulfillment[?(@.SKU=='8A-OK9F-9LI8')]..Component[?(@.Type=='Principal')]

同样,我的目标是获取“__ content__”值并按特定SKU过滤,并在Component.Type =='Principal'中。类似的东西:

$.Order..Fulfillment[?(@.SKU=='8A-OK9F-9LI8')]..Component[?(@.Type=='Principal')]..Amount..__content__

我希望能回来["8.49", "8.49"]

以下是我正在测试的JSON:

{
  "SettlementData": {},
  "Order": [
    {
      "OrderID": "XXX",
       "Fulfillment": {
        "Item": {
          "SKU": "8A-OK9F-9LI8",
          "Quantity": "1",
          "ItemPrice": {
            "Component": [
              {
                "Type": "Principal",
                "Amount": {
                  "__content__": "8.49",
                  "currency": "USD"
                }
              },
              {
                "Type": "Tax",
                "Amount": {
                  "__content__": "0.74",
                  "currency": "USD"
                }
              }
            ]
          }
        }
      }
    },
    {
      "OrderID": "XXX",
      "Fulfillment": {
        "Item": {
          "SKU": "8A-OK9F-9LI8",
          "Quantity": "1",
          "ItemPrice": {
            "Component": {
              "Type": "Principal",
              "Amount": {
                "__content__": "8.49",
                "currency": "USD"
              }
            }
          }
        }
      }
    }
  ]
}

1 个答案:

答案 0 :(得分:0)

我能够在两次传球中解决这个问题。在此示例中,#{sku}是一个Ruby插值字符串,其中包含我传入的SKU:

$.Order..Fulfillment[?(@.SKU=='#{sku}')]..ItemPrice..[?(@.Type=='Principal')].Amount.__content__

$.Order..Fulfillment..Item[?(@.SKU=='#{sku}')]..ItemPrice..[?(@.Type=='Principal')].Amount.__content__

使用Ruby gem“jsonpath”,我能够得到我需要的金额:

  amount     = JsonPath.on(settlement, "$.Order..Fulfillment[?(@.SKU=='#{sku}')]..ItemPrice..[?(@.Type=='Principal')].Amount.__content__")
    .map(&:to_f).inject(:+)
  amount2    = JsonPath.on(settlement, "$.Order..Fulfillment..Item[?(@.SKU=='#{sku}')]..ItemPrice..[?(@.Type=='Principal')].Amount.__content__")
    .map(&:to_f).inject(:+)