I need a stable and secure convertion algorithm (any language), that can produce the final output as "first class" JSON objects. Example:
jCard format: [["version", {}, "text", "4.0"],["fn", {}, "text", "Forrest Gump"]]
First-class JSON format: {"version":"4.0","fn":"Forrest Gump"}.
In python
first, I create one function named jcard_to_json that takes a jCard as input and converts it to a "first-class" JSON object. The function iterates over the items in the jCard, and for each item, it adds a key-value pair to the json_obj dictionary, where the key is the first item in the jCard thing and the value is the fourth item
Example:-
def jcard_to_json(jcard):
json_obj = {}
for item in jcard:
json_obj[item[0]] = item[3]
return json_obj
jcard = [["version", {}, "text", "4.0"], ["fn", {}, "text", "Forrest
Gump"]]
json_obj = jcard_to_json(jcard)
In Java.
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class JCardTest {
public static void main(String[] args) throws JSONException {
String jcardStr = "[\"vcard\","
+ " ["
+ " [\"version\", {}, \"float\", \"4.0\"],"
+ " [\"fn\", {}, \"text\", \"John Doe\"],"
+ " [\"gender\", {}, \"text\", \"M\"],"
+ " [\"categories\", {}, \"text\", \"computers\", \"cameras\"],"
+ " [\"number\", {}, \"integer\", 12345],"
+ " [\"adr\","
+ " { \"type\": \"work\" },"
+ " \"text\","
+ " ["
+ " \"\","
+ " \"Suite D2-630\","
+ " \"2875 Laurier\","
+ " \"Quebec\","
+ " \"QC\","
+ " \"G1V 2M2\","
+ " \"Canada\""
+ " ]"
+ " ]"
+ " ]"
+ " ]";
JSONArray jcard = new JSONArray(jcardStr);
jcard = jcard.getJSONArray(1);
JSONObject result = new JSONObject();
for (int i = 0; i < jcard.length(); i++) {
JSONArray arr = jcard.getJSONArray(i);
String name = arr.getString(0);
String dataType = arr.getString(2);
if (arr.length() == 4) {
switch (dataType) {
case "integer": {
long val = arr.getLong(3);
result.put(name, val);
}
break;
case "float": {
double val = arr.getDouble(3);
result.put(name, val);
}
break;
default:
Object val = arr.get(3);
if (val instanceof JSONArray) {
result.put(name, (JSONArray) val);
} else {
result.put(name, val.toString());
}
break;
}
} else {
JSONArray resArr = new JSONArray();
for (int j = 3; j < arr.length(); j++) {
resArr.put(arr.get(j).toString());
}
result.put(name, resArr);
}
}
System.out.println(result);
}
}
This ignores the 'parameter" part (arr.get(1)) of the jCard entries.
the code is verbose to not to hide important details. it could be written more compact.
Example is based on examples in the jCard RFC7095.
Related
I have a JSON file as below and want to convert to json with Name key , value pair ,
Eg : "name":"emailAddress",
"value" :"Trest22#gmail.com"
If have multiple JSON tags then it should break into separate tag as shown in image.
Please help
[
{
"emailAddress": "Trest22#gmail.com",
"loginName": "Testinguser222",
"firstName": "Test222",
"surName": "Test22",
"primaryPhone": "",
"companyId": 123445,
"extracompanies": "[12311,33333]",
"middleName": "Test",
"mobilePhone": 6666666666,
"fax": 87687687686
}
]
Want to convert as below
{
{
"name":"emailAddress",
"value" :"Trest22#gmail.com"
}
{
"name":"loginName",
"value":"Testinguser222"
}
{
"name":"firstName",
"value":"Test222"
}
{
"name":"surName",
"value":"Test22"
}
{ "name":"extracompanies",
"value": "[12311,33333]"
}
I am not sure if any library can do that, however, in Java, you can achieve it as shown below,
ObjectMapper mapper = new ObjectMapper();
String test = "{\n" +
" \"emailAddress\": \"Trest22#gmail.com\",\n" +
" \"loginName\": \"Testinguser222\",\n" +
" \"firstName\": \"Test222\",\n" +
" \"surName\": \"Test22\",\n" +
" \"primaryPhone\": \"\",\n" +
" \"companyId\": 123445,\n" +
" \"extracompanies\": \"[12311,33333]\",\n" +
" \"middleName\": \"Test\",\n" +
" \"mobilePhone\": 6666666666,\n" +
" \"fax\": 87687687686\n" +
" \n" +
" }";
Map<String, Object> maps = mapper.readValue(test, Map.class);
List<Map<String,Object>> converted = maps.keySet().stream().map(key -> {
Map<String,Object> internalMap = new HashMap<>();
internalMap.put("name", key);
internalMap.put("value", maps.get(key));
return internalMap;
}).collect(Collectors.toList());
String json = mapper.writeValueAsString(converted);
Output
[{"name":"emailAddress","value":"Trest22#gmail.com"},{"name":"loginName","value":"Testinguser222"},{"name":"firstName","value":"Test222"},{"name":"surName","value":"Test22"},{"name":"primaryPhone","value":""},{"name":"companyId","value":123445},{"name":"extracompanies","value":"[12311,33333]"},{"name":"middleName","value":"Test"},{"name":"mobilePhone","value":6666666666},{"name":"fax","value":87687687686}]
How can I turn a JSON object, i.e. { username: "john", password: "1234" } into an OData string query in a function using typescript? I could not find a library to do this for me (Angular 6). Here is my attempt:
function ConvertToODataString (json: Object) {
let ret_str: string = "";
for (let key in json) {
ret_str += (key + "=" + json[key] + "&");
}
if (ret_str) {
ret_str = ret_str.substr(0, ret_str.length - 1); // remove last &
}
return ret_str;
}
Does anyone know of a better way? For now, my json is not multi-leveled.
You can use for ... in to enumerate the object properties, adding each key/value pair to an array, and combine the values with Array.join:
function convertObjectToQuery(obj: Object): string {
let values = new Array<string>();
for (let prop in obj) {
values.push(`${prop} eq '${obj[prop]}'`);
}
return encodeURI("$filter=" + values.join(" and "));
}
See this stackblitz for a demo.
JSON.parse function.
Example:
var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}');
json={ "name":"John", "age":30, "city":"New York"};
var obj = JSON.parse(json+'');
I decided to use the HttpParms module instead:
import { HttpParams } from "#angular/common/http";
const params = new HttpParams()
.set("$filter", "Username eq '" + parameters["Username"] + "' and Password eq '" + parameters["Password"] + "'")
.set("$count", "true");
console.log(params.toString());
Hi I'm trying to parse out the id's from an array. I have a logging method which shows a toast:
StringBuilder data= new StringBuilder();
JSONArray arrayMovies= response.getJSONArray(KEY_MOVIES);
for (int i = 0; i < arrayMovies.length(); i++) {
JSONObject currentMovie = arrayMovies.getJSONObject(i);
String id = currentMovie.getString(KEY_ID);
data.append(id+"\n");
}
L.t(getActivity(), data.toString());
.....
But It's not parsing it out. Just getting a list of the movies.
Here is the json file:
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/tbhdm8UJAb4ViCTsulYFL3lxMCd.jpg",
"genre_ids": [
53,
28,
12
],
"id": 76341,
"original_language": "en",
"original_title": "Mad Max: Fury Road",
"overview": "An apocalyptic story set in the furthest reaches of our planet, in a stark desert landscape where humanity is broken, and most everyone is crazed fighting for the necessities of life. Within this world exist two rebels on the run who just might be"
}
]
}
Not sure, but maybe because id value has no quote, and therefore, can not be parsed as a String with getString() method
I think your code is OK, just need check the response and keys again, I have tested with hard-code the response as the String and 2 keys as the following:
String jsonString = "{\n" +
" \"page\": 1,\n" +
" \"results\": [\n" +
" {\n" +
" \"adult\": false,\n" +
" \"backdrop_path\": \"/tbhdm8UJAb4ViCTsulYFL3lxMCd.jpg\",\n" +
" \"genre_ids\": [\n" +
" 53,\n" +
" 28,\n" +
" 12\n" +
" ],\n" +
" \"id\": 76341,\n" +
" \"original_language\": \"en\",\n" +
" \"original_title\": \"Mad Max: Fury Road\",\n" +
" \"overview\": \"An apocalyptic story set in the furthest reaches of our planet, in a stark desert landscape where humanity is broken, and most everyone is crazed fighting for the necessities of life. Within this world exist two rebels on the run who just might be\"\n" +
" }\n" +
" ]\n" +
"}";
StringBuilder data= new StringBuilder();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray arrayMovies= jsonObject.getJSONArray("results");
for (int i = 0; i < arrayMovies.length(); i++) {
JSONObject currentMovie = arrayMovies.getJSONObject(i);
String id = currentMovie.getString("id");
data.append(id+"\n");
}
Log.i("BNK", data.toString());
} catch (JSONException e) {
e.printStackTrace();
}
And here is the screenshot (please pay attention to logcat):
Consider the following json example
{
"key1" : {
"k11":["vala","valb","valc"],
"k12":["vald"],
"k13":["vale","valf"]
},
"key2" : {
"key21":["valg","valh","vali"],
"key22":["valj"],
"key23":["valk","vall"]
}
}
This translates into a Map<String,Map<String,List<String>>>.
Could anyone please let me know how i can convert this in this into this complex Map object. I do a a method called constructMapType, but not sure if it handles complex Map type.
Seems to work fine with .constructMapType(Map.class, String.class, Map.class)
public static void main(String[] args) throws Exception {
final String json
= "{\n"
+ " \"key1\" : {\n"
+ " \"k11\":[\"vala\",\"valb\",\"valc\"],\n"
+ " \"k12\":[\"vald\"],\n"
+ " \"k13\":[\"vale\",\"valf\"]\n"
+ " },\n"
+ " \"key2\" : {\n"
+ " \"key21\":[\"valg\",\"valh\",\"vali\"],\n"
+ " \"key22\":[\"valj\"],\n"
+ " \"key23\":[\"valk\",\"vall\"]\n"
+ " }\n"
+ "}";
ObjectMapper mapper = new ObjectMapper();
Map<String, Map<String, List<String>>> map
= mapper.readValue(json,TypeFactory.defaultInstance()
.constructMapType(Map.class, String.class, Map.class));
for (String outerKey: map.keySet()) {
System.out.println(outerKey + ": " + map.get(outerKey));
for (String innerKey: map.get(outerKey).keySet()) {
System.out.print(innerKey + ": [");
for (String listValue: map.get(outerKey).get(innerKey)) {
System.out.print(listValue + ",");
}
System.out.println("]");
}
}
}
You could go all the way down listing all the generics down to the List<String>, but as seen above it isn't necessary. But just to show what I mean
TypeFactory factory = TypeFactory.defaultInstance();
Map<String, Map<String, List<String>>> map
= mapper.readValue(json, factory.constructMapType(
Map.class,
factory.constructType(String.class),
factory.constructMapType(
Map.class,
factory.constructType(String.class),
factory.constructCollectionType(
List.class,
String.class))));
I'm using renderJSON(Object) to return some objects as JSON values, and it's working fine except for one field. Is there an easy way to add in that one field without having to manually create the whole json template?
Play uses GSON to build the JSON string. If your one field is a specific object type, then you can easily do this by providing a customised serialisation for that type. See the documentation here
http://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserializ
However, if it is an Integer class for example, that you want to work in one way for one, and another way for another, then you may have a little more difficulty.
Example
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(SpecificClass.class, new MySerializer());
private class MySerializer implements JsonSerializer<DateTime> {
public JsonElement serialize(SpecificClass src, Type typeOfSrc, JsonSerializationContext context) {
String res = "special format of specificClass"
return new JsonPrimitive(res);
}
}
Simply do a
JsonElement elem = new Gson().toJsonTree(yourObject);
JsonObject obj = elem.getAsJsonObject();
obj.remove("xxx");
obj.addProperty("xxx", "what you want");
// other stuff ...
renderJSON(obj.toString());
etc.
After evaluating the play framework we hit a stumbling block and decision choice on serializing JSON for an external API. Allot of articles out there suggest using the Lift framework within play which just seem like extra overhead.After trying some of the frameworks / modules with in the play framework a college and myself decided to write a light weight code block that could cater for our needs.
case class User (
user_id: Int,
user_name: Option[String],
password: Option[String],
salt: Option[String]
) extends Serializable {
def toXml =
<user>
<user_id>{user_id}</user_id>
<user_name>{user_name.getOrElse("")}</user_name>
</user>
override def toJson =
"{" + JSON.key("user_id") + JSON.value(user_id) + ", " + JSON.key("user_name") + JSON.value(user_name) + "}"
}
class Serializable {
def toJson = ""
}
object JSON {
def key(x:String) = value(x) + ": "
def value(x:Any):String = {
x match {
case s:String => "\"" + s + "\""
case y:Some[String] => value(y.getOrElse(""))
case i:Int => value(i.toString)
case s:Serializable => s.toJson
case xs:List[Any] => "[" + xs.map(x => value(x)).reduceLeft(_ + ", " + _) + "]"
}
}
}
def searchUserByName(user_name: String) = {
(for (
u <- Users if u.user_name.like(("%"+user_name+"%").bind)
) yield u.*)
.list
.map(User.tupled(_))
}
def toXml(users:List[User]) = {
<users>
{ users.map(u => u.toXml) }
</users>
}
def toJson(users:List[User]) = {
"[" + users.map(u => u.toJson).reduceLeft(_ + ", " + _) + "]"
}
And from the controller.
// -- http://localhost:9000/api/users/getUser/xml
// -- http://localhost:9000/api/users/getUser/json
def getUser(requestType:String) = {
db withSession{
val user = Users.byUserName("King.Kong")
if(requestType == "xml") {
Xml(user.toXml)
} else {
user.toJson
}
}
}
//--- http://localhost:9000/api/users/searchuser/xml
//--- http://localhost:9000/api/users/searchuser/json
def searchUser(requestType:String) = {
db withSession{
val users = Users.searchUserByName("Doctor.Spoc")
if(requestType == "xml") {
Xml(Users.toXml(users))
} else {
val jsonList = Users.toJson(users)
Json(jsonList)
}
}