How to extract one substring from one Java Object in python? - java

I've a String like this:
["[Ljava.lang.Object;",[["Object0",{"key0": null, "coolKey1": "coolValue", "notCoolKey2":"something"}],["Object1",{"key3": "value1", "key4": "nonCoolValue", "Id":"importantId0", "someId":"importantId1"}],false,["Object3",{"key6": "value6", "nonkey7": "supercoolValue"}]]]
what I'm interested is these two key-value pairs:
Id:importantId0 and someId:importantId1
How can I extract these two key value pairs from this String in Python?
I've tried to use STRING.spit("DELIMITER"), but failed, any help is greatly appreciated!

That looks to be a JSON serialization and so you should use the json module to convert it to a Python object, then access the data you need from it.
import json
x = json.loads("""["[Ljava.lang.Object;",[["Object0",{"key0": null, "coolKey1": "coolValue",
"notCoolKey2":"something"}],["Object1",{"key3": "value1", "key4": "nonCoolValue",
"Id":"importantId0", "someId":"importantId1"}],false,["Object3", {"key6": "value6",
"nonkey7": "supercoolValue"}]]]""")
print x[1][1][1]["Id"]
print x[1][1][1]["someId"]

Related

Parsing a subset of JSON in Java using Jackson

Given a Json, is it possible to use Jackson to only parse out a section of the message?
Say that the data I'm interested in is buried in a deep hierarchy of fields and I simply do not care about creating DTO classes for each and every class.
Given a very simplified scenario I'd like to model the Telephone class without knowing anything about the structure before it:
...{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}....
I'm thinking something in the terms of using json-path together with deserializing just the parts I'm interested of. Some pseudo:
List<Telephone> phoneNrs = parse(".my.deep.structure.persons.phoneNumbers", List<Telephone.class>);
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree("... your JSON ...");
Using the JsonNode object you can then call get("my").get("deep").get("structure") to get the node you want.
Once you got your hands on that node, a simple call to mapper.treeToValue(myDeepJsonNode, Telephone[].class) will get you your array ofTelephone. You can get a list using a TypeReference as well.
To get to your deep JsonNode you can also use the findValue and findPath methods.
The Javadoc:
https://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/JsonNode.html
Yes, it is possible the way you have mentioned in the Pseudo code. "phoneNumbers" is a key and value returned can be passed on to Jackson deserialiying.
If the response is an array of maps then you can iterate through each one of them and use the yourResponseAsJSONObject.get('phoneNumbers') method to get the value and pass it on to Jackson
or use JsonPath as mentioned by #dimas
You can use JsonPath library. With this library you can map your JsonPath output directly into POJO's.
Pseudo:
List<Telephone> phoneNrs = JsonPath.parse(json).read("$.my.deep.structure.persons.phoneNumbers", List.class);
To do this efficiently with Jackson, use the Streaming API via the JsonParser class (http://fasterxml.github.io/jackson-core/javadoc/2.5/com/fasterxml/jackson/core/JsonParser.html).
This approach will allocate no additional memory and will not incur the cost of deserializing values for all of the skipped data. Since the code will be much longer and more difficult to read than using Jackson's ObjectMapper, only do this if profiling shows unacceptable GC activity or CPU usage during parsing.
You can skip all of the nodes that you are uninterested in until you hit the "phoneNumbers" key. Then you can call the readValueAs function to deserialize the array of phone number dictionaries like so readValueAs(new TypeReference<MyPhoneNumberType[]>()).
See also:
a tutorial on reading and writing with JsonParser: http://www.cowtowncoder.com/blog/archives/2009/01/entry_132.html
The main documentation: https://github.com/FasterXML/jackson-core

JSON Representation of HashMap

what is the Json representation of HashMap<String, String>?
I have tried this way but getting bad request error.
"userPreferences":{{"mobile":"yes"},{"email":"yes"}}
It should be like this
{ "userPreferences":{"mobile":"yes","email":"yes"} }
"userPreferences":{"mobile":"yes","email":"yes"}
The JSON you have would be invalid even as a JavaScript object, since you haven't defined property names for the two "inner" objects. A HashMap is basically a set of key-value pairs. Your JSON should look like:
"userPreferences": {
"mobile": "yes",
"email": "yes"
}

I need to transform a JsonObject into a hashmap, but the structure of the JSON is a bit different

This is the structure of the JSON that I need to transform:
{
"United Kingdom": {
"visit_count": 2,
"cities": {
"London": 2
}
},
"Netherlands": {
"visit_count": 1182,
"cities": {
"Amsterdam": 441
}
}
}
Which is basically a JSonObject, which contains an array of objects, BUT the key is the name of the country, and the right part, are the properties of the object. The same goes for the "Cities" JsonObject.
Now I tried doing this with jsonschema2pojo, but it tries to create objects after the name of the countries (United Kingdom, Netherlads) when this objects are actually the same type.
I was thinking of somehow loading the json into a hashmap, but don't know how exactly to do that. Is is possible?
Use google's Gson, it works excellent.
https://code.google.com/p/google-gson/
And take a look into here
You can try to use JSON-simple library: https://code.google.com/p/json-simple/
JSONObjects parsed by this library are literally represented as a HashMap. (org.json.simple.JSONObject extends HashMap) :-)

How to transform string with objects and array indexes into json

I receive from another program Map with string representation of elements:
Map<String,String> properties = new HashMap<String,String>() {{
put("news[0].title", "Title 1");
put("news[0].body", "Body 1");
put("news[1].title", "Title 2");
put("news[1].body", "Body 2");
}};
I need to render it into freemarker-template. In question
freemarker-flat-structure-of-passing-parameters-transfer-to-array-of-objects
we decided that it is impossible to parse this kind of values in freemarker. But freemarker can eval json.
So I need to know how to transform this map into objects or json. I need something like that:
{
"news": [
{"title": "Title1", "body": "Body1"},
{"title": "Title2", "body": "Body2"}
]
}
Names of parameters in map are unknown, not exactly "news", not exactly "title" and "body", I don't know.
May be there are some libraries for such purposes?
Since you are using your own language there, just write a parser for it. It's not a complex language after all. Also, transforming it to JSON doesn't make sense, based on what I know about the problem. Yes, the FTL expression syntax and JSON syntax overlaps quite much. But you shouldn't parse anything inside the FTL-s, just parse your language to List-s and JavaBeans and/or Map-s, and pass that plain Java object to FreeMarker.
GSon and Jackson libraries are there for conversion between Java objects and JSON strings.

Using JsonPath to extract value without knowing key

I have a json string like this:
"files": {
"fileA.c": {
"size": 100
},
"fileB.txt": {
"size": 200
}
}
I want to extract the file names, {"fileA.c","fileB.txt"}, using JsonPath. Note that the number of files is unknown.
The problem is, I don't know whether the file name is a key or a value:
If it is a key...well I certainly don't know the key name because that's the information I want to extract.
If it is a value, then what is its key?
Can I use JsonPath to extract the file names? If so, how?
If JsonPath cannot do this, is there any Java library for Json that can achieve this?
In your example, fileA.c and fileB.txt are keys, you can get them by iterating on the key in the enclosing object (which is referenced by the key "files").
I don't think JSONPath is really appropriate (or even applicable) in this case, it is designed to access elements when you know the structure of the documents, which means that basically you know the keys. It would be much easier to simply use a JSON parser.
I would suggest you to modify your data structure, to something like this;
var data = {
"files": [
{
"name": "fileA.c",
"size": 100
},
{
"name": "fileB.txt",
"size": 200
},
{
"name": "fileC.txt",
"size": 50
}
]
};
When structured like this, you can use DefiantJS (http://defiantjs.com) to query for files which sizes are larger than 100...like this:
JSON.search(data, '//*[size >= 100]/name')
DefiantJS extends the global object JSON with the method "search", with which you can query JSON structure with XPath expressions.
To see a working example with your data, check out this fiddle:
http://jsfiddle.net/jRN22/

Categories

Resources