djangoexpert djangoexpert - 3 months ago 8
JSON Question

Getting non string value as a json key in python

I'm using "ODK" integeration in one of my django project.

I'm getting a json format from a response(request.body) in a django view which is in the way that all the keys in it are non-string.
ex :

{
key1 : "value1",
key2 : "value2"
}


Since the keys in it are non string I have no idea how to access the values inside the json.I need to know what type of json this one is and how to progress it in order to convert the json to a dictionary.

This is the json file am getting:

{

token: "testauthtoken",
content: "record",
formId: "maintenance_ct",
formVersion: "",

}

Answer

As others have pointed out, this is not valid JSON, for two reasons: the unquoted key names, and the trailing comma at the end.

Your best bet, if possible, would be to fix the server code that generates this to produce correct JSON instead. Perhaps that code is creating the "JSON" by manually pasting strings together? If so, you could change it to use json.dumps() instead, so it produces valid JSON.

Failing that, you could preprocess the "JSON" text to surround the key names with quotes and to remove the trailing comma. This can be a bit fragile, but if you know the format of the input data will remain similar, it's one way to do it:

import json, re

badJson = '''
{

token: "testauthtoken",
content: "record",
formId: "maintenance_ct",
formVersion: "",

}
'''

print( 'badJson:' )
print( badJson )

goodJson = re.sub( r'\n\s*(\S+)\s*:', r'\n"\1":', badJson )
goodJson = re.sub( r',\s*}', r'\n}', goodJson )
print( 'goodJson:' )
print( goodJson )

goodData = json.loads( goodJson )
print( 'goodData:' )
print( goodData )

This prints:

badJson:

{

token: "testauthtoken",
content: "record",
formId: "maintenance_ct",
formVersion: "",

}

goodJson:

{
"token": "testauthtoken",
"content": "record",
"formId": "maintenance_ct",
"formVersion": ""
}

goodData:
{'formId': 'maintenance_ct', 'content': 'record', 'token': 'testauthtoken', 'formVersion': ''}

When I first wrote this answer I misunderstood the question and provided a JavaScript solution instead of Python. In case this is useful for anyone I'll leave it here:

While the input text is not valid JSON, it is a valid JavaScript object literal. So you can treat it as such and use eval() to parse it. In fact, this is how libraries such as jQuery parsed JSON in old browsers that didn't support JSON.parse().

BEWARE: You had best be sure that you trust the source of this data string, since you are treating it as executable code!

// Set up a string like your input data string.
// All on one line here so we can use a string constant for testing,
// but your multiline data string will work the same.
var dataString = '{ token: "testauthtoken", content: "record", formId: "maintenance_ct", formVersion: "", }'

// Now use eval() to convert it to a JavaScript object.
// We wrap the string in parentheses so it will parse as an expression.
var data = eval( '(' + dataString + ')' );

// Finally, we can access the values.
console.log( 'token: ', data.token );
console.log( 'content: ', data.content );
console.log( 'formId: ', data.formId );
console.log( 'formVersion: ', data.formVersion );

Comments