0

I have a process that parses through similar but different json objects from different companies. For example:

COMPANY A Json looks like this:

{
   "str": "502 Oak Lane", 
   "city": "Los Angeles", 
   "st": "CA", 
   "zip": "91403"
}

COMPANY B Json looks like this:

{
   "streetaddress": "999 Orange Ave", 
   "cityname": "Los Angeles", 
   "statename": "CA", 
   "zipcode": "92039"
}

COMPANY C Json looks like this:

{
 "locations": [
  {
   "streetaddress": [
    "52 Pine Street"
   ], 
   "sublocality1": "Los Angeles", 
   "sublocality2": "CA", 
   "postal_code": "91403"
  }, 

  {
   "streetaddress": [
    "252 Main St"
   ], 
   "sublocality1": "Los Angeles", 
   "sublocality2": "CA", 
   "postal_code": "91403"
  }

 ] 
}

I also have Company D, E, F... and everybody formats their json a bit differently. I'm trying to write a generic parser to go through and get the 'city' from each of these objects. It's easy enough to do for Company A or company B.

string citynode = "$.city";  //ex. for Company A
string GetCity(jsoninputtext, citynode);
...

string citynode = "$.cityname";  //ex. for Company B
string GetCity(jsoninputtext, citynode);
...

function GetCity(string jsoninputtext, string citynode)
{
    var jsonDynamic = JsonConvert.DeserializeObject<dynamic>(jsoninputtext);
    string city = (string)jsonDynamic.SelectToken(citynode).Value;
    return city;
}

However, I'm stuck with objects like Company C which have multiple locations or that are children of other nodes ('locations'). All I need to get is the FIRST 'city', I don't care about any subsequent ones but I don't know how to do this with my generic GetCity() function. Any help would be greatly appreciated.

1
  • 1
    Just a side note, why do you need a generic parser for all formats? You can create a generic interface for parser and have a specific implementation for every source, it's easier to maintain in future and test Commented May 16, 2020 at 19:45

2 Answers 2

2

For Company C you can use the expression $.locations[0].sublocality1 to get the first city.

As an aside, you can simplify your code and get rid of the .Value. Casting the token to a string will work and will also eliminate the need for a null check if there aren't any locations. The city itself will be null in that case, which I think is what you would want.

string city = (string)jsonDynamic.SelectToken(citynode);

Fiddle: https://dotnetfiddle.net/g6HG0L

Sign up to request clarification or add additional context in comments.

Comments

0

Not sure that it is the best option, but you can try something like this for start:

public static string GetCity(string jsoninputtext, string citynode)
{
    var x = JsonConvert.DeserializeObject<JObject>(jsoninputtext);

    return x.DescendantsAndSelf()
        .First(t => t.SelectToken(citynode) != null)
        .SelectToken(citynode)
        .Value<string>();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.