Forum Discussion

Henchway's avatar
Henchway
Contributor
3 years ago

Match operator: match object key with special characters

Hi all,

I’m facing and issue where i would like to match some properties of an object within an array and then select a specific object key for the result.

Since my source data is Workday XML, I have namespaces prepended to the object keys.
In this match, i would like to retrieve the ‘wd:Email_Address’ element, but i believe that since i put that in quotes, it doesn’t realize that i want to declare it as variable. When i don’t do that, it will also not accept it due to the colon.

Does anyone have a suggestion on how to deal with this?

match $['wd:Worker_Data']['wd:Personal_Data']['wd:Contact_Data']['wd:Email_Address_Data'] {
 [..., { "wd:Usage_Data": { "@wd:Public": "1"}, 'wd:Email_Address' }, ...] => 'wd:Email_Address'
}

Here’s an exemplary data set that i’d like to match (the bulk before is omitted):

  "wd:Email_Address_Data": [
  {
    "wd:Email_Address": "Thomas.scheibelhofer@kapsch.net",
    "wd:Usage_Data": {
      "@wd:Public": "1",
      "wd:Type_Data": {
        "@wd:Primary": "1",
        "wd:Type_Reference": {
          "@wd:Descriptor": "Work",
          "wd:ID": [
            {
              "@wd:type": "WID",
              "$": "..."
            },
            {
              "@wd:type": "Communication_Usage_Type_ID",
              "$": "WORK"
            }
          ]
        }
      }
    },
    "wd:Email_Reference": {
      "@wd:Descriptor": "EMAIL_REFERENCE-3-7789",
      "wd:ID": [
        {
          "@wd:type": "WID",
          "$": "..."
        },
        {
          "@wd:type": "Email_ID",
          "$": "..."
        }
      ]
    },
    "wd:ID": "..."
  },
  {
    "wd:Email_Address": "test@test.test",
    "wd:Usage_Data": {
      "@wd:Public": "0",
      "wd:Type_Data": {
        "@wd:Primary": "1",
        "wd:Type_Reference": {
          "@wd:Descriptor": "Home",
          "wd:ID": [
            {
              "@wd:type": "WID",
              "$": "..."
            },
            {
              "@wd:type": "Communication_Usage_Type_ID",
              "$": "HOME"
            }
          ]
        }
      }
    },
    "wd:Email_Reference": {
      "@wd:Descriptor": "...",
      "wd:ID": [
        {
          "@wd:type": "WID",
          "$": "..."
        },
        {
          "@wd:type": "Email_ID",
          "$": "..."
        }
      ]
    },
    "wd:ID": "..."
  }
  ]
```json

Best regards
Thomas

3 Replies

  • Supratim's avatar
    Supratim
    Contributor III

    @Henchway Sorry I didn’t 100% understand your requirement but as per my understanding you are trying to fetch email address where public ==1 from an wd:Email_Address_Data array. If that’s the case you can try either of the below expression.

    jsonPath($, “[‘wd:Email_Address_Data’][?(value[‘wd:Usage_Data’][‘@wd:Public’] == 1)][‘wd:Email_Address’]”).pop()

    or
    sl.ensureArray($[‘wd:Email_Address_Data’]).filter((val,index)=> val.hasPath(“[‘wd:Usage_Data’][‘@wd:Public’]”)).find((ele,index)=> ele[‘wd:Usage_Data’][‘@wd:Public’] == 1)[“wd:Email_Address”]

    • Henchway's avatar
      Henchway
      Contributor

      Hi Supratim,

      thanks for the suggestion, that’s the way I’m currently doing it, however, I need to check not only ‘public’, but several other elements in different levels of the json as well as some conditional logic and that gets fairly tedious once it reaches a certain size.
      Here i would like to specifically solve this with the matcher and to know whether it’s possible to output a variable which includes special characters such as a colon.

      Best regards
      Thomas

    • Henchway's avatar
      Henchway
      Contributor

      To elaborate a bit more, i now removed the XML namespaces in the document and then it works like a charm.

      E.g. in the following i’m checking three different attributes and two different cases: one where the data is delivered in an array and the other one in an object:

      match $Worker_Data.Personal_Data.Contact_Data.Email_Address_Data{
       [..., { "Usage_Data": { "@Public": "1", "Type_Data": {"@Primary": "1", "Type_Reference": {"@Descriptor": "Work"}}}, Email_Address }, ...] => Email_Address,
      { "Usage_Data": { "@Public": "1", "Type_Data": {"@Primary": "1", "Type_Reference": {"@Descriptor": "Work"}}}, Email_Address } => Email_Address
      }
      

      When trying this with jsonPath and a ternary operator, it gets very convoluted:

      typeof $['wd:Worker_Data']['wd:Personal_Data']['wd:Contact_Data']['wd:Email_Address_Data'] == 'array' 
      ?
       jsonPath($, "$['wd:Worker_Data']['wd:Personal_Data']['wd:Contact_Data']['wd:Email_Address_Data'][?(value['wd:Usage_Data']['@wd:Public'] == '1' 
      && value['wd:Usage_Data']['wd:Type_Data']['@wd:Primary'] == '1' 
      && value['wd:Usage_Data']['wd:Type_Data']['wd:Type_Reference']['@wd:Descriptor'] == 'Work')]['wd:Email_Address']").pop()
      : 
      ($['wd:Worker_Data']['wd:Personal_Data']['wd:Contact_Data']['wd:Email_Address_Data']['wd:Usage_Data']['@wd:Public'] == '1' 
      && $['wd:Worker_Data']['wd:Personal_Data']['wd:Contact_Data']['wd:Email_Address_Data']['wd:Usage_Data']['wd:Type_Data']['@wd:Primary'] == '1' 
      && $['wd:Worker_Data']['wd:Personal_Data']['wd:Contact_Data']['wd:Email_Address_Data']['wd:Usage_Data']['wd:Type_Data']['wd:Type_Reference']['@wd:Descriptor'] == 'Work'
      ?
      $['wd:Worker_Data']['wd:Personal_Data']['wd:Contact_Data']['wd:Email_Address_Data']['wd:Email_Address']
      :
      null
      )
      

      Of course i wouldn’t want to remove the namespaces every time before i want to use the match operator, do you have a suggestion how to achieve with with match?