Search code examples
jsonpath

How to Find JSON Path element that matches a specific filter


I need to get just the element that matches a specific ID from the data below ( I am using jsonpath.com ) .

If I try $.StatementLine.*[?(StatementLineID='780e0c0f-f62f-42f8-96ad-9a2db62e6271')] I just get all the elements.

{
  "@xmlns:i": "http://www.w3.org/2001/XMLSchema-instance",
  "StatementLine": [
    {
      "Amount": "-1.4000",
      "AnalysisCode": "Fee",
      "BankRuleMatch": {
        "BankRuleID": "08ec6ff4-bb38-45cd-908c-f6c2b3f62bba",
        "BankRuleTemplateInvoiceID": "be462ac0-9be6-45aa-81ee-817248b7023b",
        "ContactFieldToMatchCode": "MATCHFIELD/CONTACT/CONTACTID",
        "LineItemCount": "1",
        "PaidToName": "PayPal",
        "ReferenceFieldToMatchCode": "MATCHFIELD/REFERENCE/REFERENCE",
        "RuleName": "PayPal - Fees",
        "RuleType": "BANKRULETYPE/CASHPAY",
        "StatementLineID": "20ad2616-2d63-4b87-ab4a-49e7c474d40e"
      },
      "ChequeNo": null,
      "Notes": "Fee",
      "Payee": "PayPal (Related to 3BE10345GW6043408)",
      "PostedDate": "01 Nov 2021",
      "StatementID": "93424a06-586e-47c0-92b0-81ea86ff75b9",
      "StatementLineID": "20ad2616-2d63-4b87-ab4a-49e7c474d40e",
      "Type": "DEBIT"
    },
    {
      "Amount": "90.4800",
      "AnalysisCode": "Express Checkout API",
      "ChequeNo": null,
      "MatchedTransactions": {
        "MatchedTransaction": {
          "Amount": "90.4800",
          "IsPayRunTransaction": "false",
          "PaidToName": "Payment: xxxxxxxxxxx",
          "Reconciled": "false",
          "Reference": "xxxxxxxxxxx",
          "StatementLineID": "3346bbcb-3c4a-4985-bf51-a503bf7260a5",
          "SubsidiaryID": "5361e537-39e6-4724-a65c-ef3aed9de1e4",
          "SubsidiaryType": "SUBSTYPE/BANK",
          "TotalCount": "1",
          "TransactionDate": "02 Nov 2021"
        }
      },
      "Payee": "xxxxxxxxxxxxxxxxxxxxx",
      "PostedDate": "01 Nov 2021",
      "Reference": "5XL98374E2648801T",
      "StatementID": "93424a06-586e-47c0-92b0-81ea86ff75b9",
      "StatementLineID": "3346bbcb-3c4a-4985-bf51-a503bf7260a5",
      "Type": "CREDIT"
    },
    {
      "Amount": "-3.6500",
      "AnalysisCode": "Fee",
      "BankRuleMatch": {
        "BankRuleID": "08ec6ff4-bb38-45cd-908c-f6c2b3f62bba",
        "BankRuleTemplateInvoiceID": "be462ac0-9be6-45aa-81ee-817248b7023b",
        "ContactFieldToMatchCode": "MATCHFIELD/CONTACT/CONTACTID",
        "LineItemCount": "1",
        "PaidToName": "PayPal",
        "ReferenceFieldToMatchCode": "MATCHFIELD/REFERENCE/REFERENCE",
        "RuleName": "PayPal - Fees",
        "RuleType": "BANKRULETYPE/CASHPAY",
        "StatementLineID": "780e0c0f-f62f-42f8-96ad-9a2db62e6271"
      },
      "ChequeNo": null,
      "Notes": "Fee",
      "Payee": "PayPal (Related to 5XL98374E2648801T)",
      "PostedDate": "01 Nov 2021",
      "StatementID": "93424a06-586e-47c0-92b0-81ea86ff75b9",
      "StatementLineID": "780e0c0f-f62f-42f8-96ad-9a2db62e6271",
      "Type": "DEBIT"
    }
  ]
}

The result I need to get is:

{
  "Amount": "-3.6500",
  "AnalysisCode": "Fee",
  "BankRuleMatch": {
    "BankRuleID": "08ec6ff4-bb38-45cd-908c-f6c2b3f62bba",
    "BankRuleTemplateInvoiceID": "be462ac0-9be6-45aa-81ee-817248b7023b",
    "ContactFieldToMatchCode": "MATCHFIELD/CONTACT/CONTACTID",
    "LineItemCount": "1",
    "PaidToName": "PayPal",
    "ReferenceFieldToMatchCode": "MATCHFIELD/REFERENCE/REFERENCE",
    "RuleName": "PayPal - Fees",
    "RuleType": "BANKRULETYPE/CASHPAY",
    "StatementLineID": "780e0c0f-f62f-42f8-96ad-9a2db62e6271"
  },
  "ChequeNo": null,
  "Notes": "Fee",
  "Payee": "PayPal (Related to 5XL98374E2648801T)",
  "PostedDate": "01 Nov 2021",
  "StatementID": "93424a06-586e-47c0-92b0-81ea86ff75b9",
  "StatementLineID": "780e0c0f-f62f-42f8-96ad-9a2db62e6271",
  "Type": "DEBIT"
}

Solution

  • $.StatementLine[?(@.StatementLineID=='780e0c0f-f62f-42f8-96ad-9a2db62e6271')]
    

    So first:

    $.StatementLine is the path to the array containing the element you want. We could just say $.StatementLine[2], but if you don't know the index ahead of time, you want to filter that array.

    We replace the index 2 with a filter expression. ? is the filter operator, so we will want to replace the hardcoded 2 with ?(condition) instead, giving us $.StatementLine[?(condition)].

    Our condition will use StatementLineID and the id we're looking for, but just like the main expression uses $. to indicate the top level container, the filter uses @. to indicate the current element being checked. In this case you can think of @. as each element of the array, and we're going to pass StatementLineID to that.

    The only other thing is to pass it the value we're looking for. Two things here. The test of equiality is ==, not =. Also, string values need to be wrapped in quotes, either single or double, so your condition is @.StatementLineID=='780e0c0f-f62f-42f8-96ad-9a2db62e6271'. Just put that into the filter, and you'll have the whole expression.

    Reference: https://docs.oracle.com/cd/E60058_01/PDF/8.0.8.x/8.0.8.0.0/PMF_HTML/JsonPath_Expressions.htm