-1

I have a JSON string:

{"emailId":[],"Age":[],"siblings":[],"addedGroupIds":[],"role":{"name":"x","description":"y","Permissions":[],"clientId":102}}

I want to replace value from every key-value pair(unless the value itself is a dictionary,eg:"role"). I converted the above mentioned string to a dictionary in somerandomFunc() and then sent this dictionary to iterator(). Iterator() will recursively check if the value in each key-value pair is a dictionary or not. If the value is not a dictionary, it will send the key to smartScanner() where I will be replacing the value of the recieved key with myTestString

def somerandomfunc(self,JSONString):
    payload=simplejson.loads(JSONString)
    self.payload=payload
    iterator(payload)

def iterator(self,payload):
    for i in payload:
        if isinstance(payload[i],dict):
            self.iterator(payload[i])
        else:
            self.smartScanner(i)

def smartScanner(self,i):
    mytestString='">qqqq'
    if (self.payload.has_key(i)):
        self.payload[i]=mytestString
    print "%s:%s"%(i,self.payload.has_key(i))

I get the following output:

existingGroupIds:True
existingUserIds:True
assetPermissions:False
name:False
clientId:False 
description:False
removedGroupIds:True
removedUserIds:True
addedGroupIds:True
addedUserIds:True

Which means that if statement in smartScanner() failed for keys "assetPermissions","name","clientId" and "description". And I wasn't able to replace the values of these keys with myteststring. I can understand the reason it failed was because it tried to access payload["name"] instead of payload["role"]["name"]

How do I change my logic so that I be able to replace the values even for keys "assetPermissions","name","clientId" and "description"? And that my program does not break no matter any hierarchies of dictionary are present in the JSON payload

  • What is self.payload? Is this instance attribute different than payload? BTW, in python usually we don't wrap `if` conditionals in parentheses unless they are useful, otherwise someone who is used to reading python will expect it to do something. – juanpa.arrivillaga Jun 24 '16 at 21:21
  • I want to replace the values "x","y" and "102" with myTestString @PadraicCunningham – Virtue Crazy Jun 24 '16 at 21:22
  • Yes, my program fails for nested dictionary. I am able to replace values for keys "email", "Age",etc. but not for "assetPermissions","name","clientId" and "description" @PadraicCunningham – Virtue Crazy Jun 24 '16 at 21:27
  • @juanpa.arrivillaga: my bad, I have edited the code. Please look for changes in somerandomfunc(). I have also defined payload as a global variable – Virtue Crazy Jun 24 '16 at 21:29

1 Answers1

0

I believe you are over-complicating it with your "smartscanner" function. Here is an approach, not using a class, but you should be able to convert it to a class method easily:

In [16]: example = {"emailId":[],"Age":[],"siblings":[],"addedGroupIds":[],"role":{"name":"x","description":"y","Permissions":[],"clientId":102}}

In [17]: def iterator(payload):
    ...:     for i in payload:
    ...:         if isinstance(payload[i],dict):
    ...:             iterator(payload[i])
    ...:         else:
    ...:             payload[i] = '">qqqq'
    ...:             

In [18]: iterator(example)

In [19]: example
Out[19]: 
{'Age': '">qqqq',
 'addedGroupIds': '">qqqq',
 'emailId': '">qqqq',
 'role': {'Permissions': '">qqqq',
  'clientId': '">qqqq',
  'description': '">qqqq',
  'name': '">qqqq'},
 'siblings': '">qqqq'}

EDIT

OK, so try this:

def iterator(payload):
   for i in payload:
       if isinstance(payload[i],dict):
           iterator(payload[i])
       else:
           temp = payload[i]
           payload[i] = '">qqqq'
           send_POST(self.payload)
           payload[i] = temp

Where send_POST is a function that wraps your POST call.

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • As far as I understood that is what was required. Modifying it would be simple by adding a conditional to prevent assigning the string. – juanpa.arrivillaga Jun 24 '16 at 21:36
  • *I want to replace value from every key-value pair(unless the value itself is a dictionary,eg:"role").* – juanpa.arrivillaga Jun 24 '16 at 21:39
  • I see. Well, I think there has been ambiguous and contradictory specifications, so perhaps Virtue Crazy can finally specify exactly what is being asked. – juanpa.arrivillaga Jun 24 '16 at 21:45
  • Yes I do want to replace all the values but one by one. This is because, after changing a single value with myTestString, I want to send a POST call with the modified payload, then reset the dictionary to the original one, make the next change, send the POST call and then repeat. Sending the POST call was the original purpose of smartScanner() and that's why I was replacing the values in smartScanner() instead of in iterator(). The solution that you provided changes all the values and I cannot find room to make the POST call. – Virtue Crazy Jun 24 '16 at 21:59
  • @VirtueCrazy see my edit. – juanpa.arrivillaga Jun 24 '16 at 22:23
  • This solves my problem. Thanks @juanpa.arrivillaga – Virtue Crazy Jun 25 '16 at 07:39