Need to update the value in a Json node - json

I have some arbitrary Json and I want to replace some of the text fields with objects. The text fields have a certain pattern, for example, say they start with a dollar sign $. I have no idea in advance what the keys are.
The object I want to replace it with is a Pojo probably a Map or List, which can be easily serialized to Json
For example
{
"key1" : "some value",
"key2" : "$replaceMe",
"key3" : {
"key4" : "more complex",
"key5" : "$andMe"
}
So after the replacement, the object would look something like this
{
"key1" : "some value",
"key2" : {},
"key3" : {
"key4" : "more complex",
"key5" : {}
}
where {} represents the new object that replaced the string that was previously there
I figured out several ways to traverse the tree, but can't figure out a good way to keep track of the objects to be replaced and how to replace them.

You can iterate over the JsonNode nodes of your json file checking the child nodes of every parent node : you can check if there are children nodes representing basic JSON String value with theJsonNode#isTextual method and if their text starts with the dollar sign like below:
ObjectMapper mapper = new ObjectMapper();
//with a generic parent jsnode and one child node of it
if (child.isTextual() && child.asText().startsWith("$")) {
//delete the old text value and create an empty objectnode
((ObjectNode)parent).set(fieldName, mapper.createObjectNode());
}
For the creation of an empty ObjectNode child you can use the ObjectMapper#createObjectNode method like I have done above.

Related

Groovy compare two json with unknown nodes names and values

I have a rest API to test and I have to compare two json responses. Below you can find a structure of the file. Both files to compare should contains the same elements but order might be different. Unfortunately the names, the type (simple, array) and the number of keys (root, nodeXYZ) are also not known.
{"root": [{
"node1": "value1",
"node2": "value1",
"node3": [
{
"node311": "value311",
"node312": "value312"
},
{
"node321": "value321",
"node322": "value322"
}
],
"node4": [
{
"node411": "value411",
"node412": "value413",
"node413": [ {
"node4131": "value4131",
"node4132": "value4131"
}],
"node414": []
}
{
"node421": "value421",
"node422": "value422",
"node423": [ {
"node4231": "value4231",
"node4232": "value4231"
}],
"node424": []
}]
"node5": [
{"node51": "value51"},
{"node52": "value52"},
]
}]}
I have found some useful information in
Groovy - compare two JSON objects (same structure) and return ArrayList containing differences
Getting node from Json Response
Groovy : how do i search json with key's value and find its children in groovy
but I could not combine it to an solution.
I thought the solution might look like this:
take root
get root children names
check if child has children and get their names
do it to the lowest leve child
With all names in place comparing should be easy (I guess)
Unfortunately I did not manage to get keys under root
Just compare the slurped maps:
def map1 = new JsonSlurper().parseText(document1)
def map2 = new JsonSlurper().parseText(document2)
assert map1 == map2
Try the JSONassert library: https://github.com/skyscreamer/JSONassert. Then you can use:
JSONAssert.assertEquals(expectedJson, actualJson, JSONCompareMode.STRICT)
And you will get nicely formatted deltas like:
java.lang.AssertionError: Resources.DbRdsLiferayInstance.Properties.KmsKeyId
Expected: kms-key-2
got: kms-key

Flat csv data to Json

I am trying to process a Json data in Java. I have the data in below format (it is nested data structure with arrays etc.)
person.name,person.friend[0],person.friend[1],person.address.city,person.address.country
1,x,y,kolkata,india
2,a,b,london,uk
The first line is header denoting the nested object hierarchy. I want a json in below format,
{
"data" : [
{
"name" : "1",
"friend" : ["x","y"],
"address" : { "city" : "kolkata", "country" : "india" }
},
{
"name" : "2",
"friend" : ["a","b"],
"address" : { "city" : "london", "country" : "uk" }
} ]
}
The object structure is dynamic and I dont know the columns or header in advance, i.e. I can not use any predefined POJO to get populated with the data. In this example, it "Person" object but it may be any object structure.
I have gone through Jackson or Gson API, but none seems to fulfill this requirement. Is there any API that can help? or any other wayout?
Thanks
You need to do it in 2 steps.
First, you have to parse your CSV. I recommend superCSV. Parsing CSV may be fancy sometimes, so I really recommend you to use a library for that.
Second, you can serialize into JSON. Then you can use GSON, jackson, flexjson, whatever.
After a long Google...I found that the only option is to represent a collection based object structure in flat file is repeated rows,
person.name,person.friends,person.address.city,person.address.country
1,x,kolkata,india
1,y,kolkata,india
2,a,london,uk
2,b,london,uk
where the non-array elements repeats. We need to form a json from this, then need to filter or club the same object by its ID (here person.name)

How can you use GWT AutoBeans to parse a JSON message when some of the return values could be an object or a collection of objects?

Is it possible to parse a JSON message using GWT AutoBeans when one of the objects returned may be a collection but not always?
For example, if I have a JSON message returning an author and his/her associated writings, it's possible that there could be zero or more books being returned.
{ "name" : "William Gibson", "books" : { bookname : "Neuromancer" } }
could be one response, but so could this:
{ "name" : "William Gibson", "books" : [ { bookname: "Neuromancer"}, { bookname : "Pattern Recognition" } ] }
When I attempt to model this with an interface to be used for marshalling with an AutoBean, I get "expecting indexed data" errors if only one book is returned.
Interface for the AutoBean:
public interface Author {
#PropertyName(value="name")
String getAuthorName();
#PropertyName(value="book")
List<String> getBooks();
}
Snippet of error:
java.lang.AssertionError: Expecting indexed data
at com.google.web.bindery.autobean.shared.impl.SplittableList.<init>(SplittableList.java:64)
Is this not possible with AutoBeans?
(Note: using GWT 2.5.0 GA)
If you have a List, AutoBeans expects a JSON array. That array could contain zero, one or more elements, but it has to be an array (or be absent).
I think you can make your getBooks method return a Splittable though. You could then know whether it's an array (isIndexed()) or not. If you need the array to contain objects, you'd then have to iterate on the array (size() and get(int)) and pass each element to AutoBeanCodex.decode() to decode them (or directly pass the splittable if it's not an array).

Can I get MOXy to not output an element when generating json?

An instance of my JAXB Object model contains an element that I want output when I generate Xml for the instance but not when I generate json
i.e I want
<release-group>
<type>Album</type>
<title>Fred</title>
</release-group>
and
"release-group" : {
"title" : "fred",
},
but have
"release-group" : {
"type" : "Album",
"title" : "fred"
},
Can I do this using the oxml.xml mapping file
This answer shows how I can do it for attributes using the transient keyword, Can I get MOXy to not output an attribute when generating json? but I cannot get that to work for an element.
Sorry problem solved, a bit of confusion on my part.
The example I gave above didn't actually match the true situation accurately, type was actually output as an attribute for Xml, but use of transient didnt work because it had been renamed in the JAXB
#XmlAttribute(name = "target-type", required = true)
#XmlSchemaType(name = "anyURI")
protected String targetType;
So adding
<java-type name="ReleaseGroup">
<java-attributes>
<xml-transient java-attribute="targetType"/>
</java-attributes>
</java-type>
worked, previously I was incorrectly doing
<java-type name="ReleaseGroup">
<java-attributes>
<xml-transient java-attribute="target-type"/>
</java-attributes>
</java-type>

Can you flatten a nested JSON structure into a single autobean?

Assuming the following JSON structure:
{
\"is_something\": false,
\"name\": \"Some Name\",
\"subtype\": {
\"total\": 0.0
}
}
Instead of creating two autobean interfaces (one for the whole structure and one for the subtype), I would like to have one which contains all the properties.
public interface ExampleAutoBean {
#PropertyName("is_something")
boolean isSomething();
String getName();
#PropertyName("subtype.total")
double getTotal();
}
So, the getTotal() method is expected to contain the total property of the nested subtype in the JSON structure. I can't find any documentation in the source code or online which states whether or not this is possible.
Thanks in advance!
Nope: AutoBeans are designed to be a mapping from the JSON structure to Java interfaces, plus or minus collections like List, Set, and Map and String encodings of a long or a Date. Additionally, it is legal to have json like the following:
{
"some.property.with.dots" : "abcd",
"name" : "wxyz"
}
If the . character could only be used for traversing into sub-objects, there would be no way to have a getter for the first property.