question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JsonPath filters on multi-nav properties, but fails on single object

See original GitHub issue

I’m struggling to understand what’s wrong with my queries that attempt to traverse a hierarchical JSON output of SAP SuccessFactors OData endpoint. JSON Path recursive descent and filtering seems to work inconsistently: it works on arrays (JArray), but fails on single objects (JObject).

Source/destination types

No specific types, actually, just fiddling with JSON Path JToken.SelectToken or SelectTokens methods output. The business case was to process SAP SuccessFactors REST OData endpoint query results.

Source/destination JSON

Simplified JSON may look like this.

{
	"d": {
		"results": [{
			"__metadata": {
				"type": "SFOData.PerPersonal"
			},
			"property": "value",
			"objectNav": {
				"__metadata": {
				"type": "SFOData.PerPerson"
				},
				"personIdExternal":"1234",
				"arrayNav": { 
					"results": [{
                                "__metadata": {
                                    "type": "SFOData.PerPhone"
                                },
                                "phoneType": "21735",
                                "phoneNumber": "+7 (000) 000-42-34"
                            }, {
                                "__metadata": {
                                    "type": "SFOData.PerPhone"
                                },
                                "phoneType": "10876", 
                                "phoneNumber": "775715"
                            }]
					}
				}
			}]		
	}
}

Expected behavior

I expect the SelectToken/SelectTokens with recursive descent operator to work consistently regardless of the presence of array or lack thereof.

Actual behavior

Successful query JSON Path "$..*[?(@.__metadata.type=='SFOData.PerPhone')].phoneNumber" yields "775715"
No results for JSON Path "$..*[?(@.__metadata.type=='SFOData.PerPerson')].personIdExternal"

Steps to reproduce

        [Test]
        public async Task SfODataDemo()
        {
            JToken sfodataJson;
            string[] successfulQueries = new [] {
              "$..results[?(@.__metadata.type=='SFOData.PerPhone')].phoneNumber",
              "$..*[?(@.__metadata.type=='SFOData.PerPhone')].phoneType",
              "$..*[?(@.__metadata.type=='SFOData.PerPhone')].phoneNumber"
            }, failingQueries = new [] {
              "$..*[?(@.__metadata.type=='SFOData.PerPerson')].personIdExternal",
            };

            // read asynchronously from a file
            using (TextReader textReader = new StreamReader(new FileStream(ResolvePath(@"sfodata.json"), FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)))
            {
                sfodataJson = await JToken.LoadAsync(new JsonTextReader(textReader));
            }

            foreach (string jsonPath in successfulQueries){
              JToken record = sfodataJson.SelectToken(jsonPath);
            }

            foreach (string jsonPath in failingQueries){
              JToken record = sfodataJson.SelectToken(jsonPath);
            }
            
        }

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
JamesNKcommented, Aug 28, 2020

_metadata has one underscore.

0reactions
AKrasheninnikovcommented, Sep 3, 2020

So I took the sources and by debugging, found that * is to blame in some cases.

Having processed the same JSON with JsonPath expressions differing only in the asterisk before the brackets, the one without asterisk works as expected, while the one with an asterisk returns an empty set.

JsonPath query should succeed:  "$..[?(@.__metadata.type=='SFOData.FODepartment')].name_ru_RU"
[SUCCESS] at 109:43 found {"__metadata": {
  "uri": "https://demo.sapsf.com/odata/v2/FODepartment(externalCode='DEP002051',startDate=datetime'2019-11-01T00:00:00')",
  "type": "SFOData.FODepartment"
}}
...
[SUCCESS] at 409:43 found {"__metadata": {
  "uri": "https://demo.sapsf.com/odata/v2/FODepartment(externalCode='DEP001148',startDate=datetime'2019-11-01T00:00:00')",
  "type": "SFOData.FODepartment"
}}
[SUCCESS] [RESULT] {Отдел блаблабла}

JsonPath query should succeed:  "$..*[?(@.__metadata.type=='SFOData.FODepartment')].name_ru_RU"
JsonPath query FAILED "$..*[?(@.__metadata.type=='SFOData.FODepartment')].name_ru_RU" returned an empty set

image

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to filter a non-array in JsonPath
I was trying to test if a given property was equal to a given string, and if so, return the entire root object....
Read more >
[Fixed] Workflows JSONpath Issue: Array brackets always ...
[Fixed] Workflows JSONpath Issue: Array brackets always present when using filters. This issue is now fixed. The root cause was a shim we...
Read more >
JSONPath Reference | ReadyAPI Documentation
All of the JSONPath expressions (including property names and values) are case-sensitive. Filters. Apply filters to JSON arrays and objects to get a...
Read more >
Using JSONPath effectively in AWS Step Functions
This post uses a sample application to highlight effective use of JSONPath and data filtering strategies that can be used in Step Functions....
Read more >
Writing JSONPath Expressions - Hevo Data
JSONPath is a query language for JSON, similar to XPath for XML. It allows you to select and extract data from a JSON...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found