Add/Remove elements in a JSON Array in Scala/Play - json

I have a pretty complex JSON object that contains, among other things, some JSON arrays that I need to update, removing and adding elements.
To do that I'm trying to use a JsPath that point directly to the object inside the array that I need to remove, something like:
/priceLists(1)/sections(0)/items(0)
to remove the element I tried to use json.prune and it doesn't work, I get this error: error.expected.jsobject
Would would be the best way to do that?

Your question is lacking a precise context (i.e., structure of your json data), but let's do with what we have.
The error message you get is clear, you can only call prune on a json object, to prune one of its values. You can't use it to prune an element of a json array.
I can only advise you to use json.update, stating that like prune, update only works on json objects. In the body of the update, work on your arrays as you usually do with scala/java data types.
__.json.update(__.reads[JsArray].map { jsArray =>
val removedElement = JsArray(jsArray.value.filter(_ == ???))
val addedElement = removedElement :+ JsBoolean(true)
addedElement
})

Related

ImmutableJS: how to convert to JSON an opaque variable

I have an opaque variable on my hand. I know it can be an object, a primitive value, an immutable, or an object whose values can be immutables.
I need to convert deeply this object to json for logging.
The following does not work, because it does not cover the case where the immutables are nested inside a real json object:
const json = isImmutable(obj)
? obj.toJS()
: obj
Is there a simple way to convert my opaque structure to json?
I know nesting immutables in non immutables may not be such a good idea. Still looking for a simple solution that does not involve large refactorings.
Try this
console.log(Immutable.fromJS(obj).toJS());
Here, first step is to convert the entire "obj" to immutable using fromJS(). Doing so will make all the nested plain objects and arrays immutable. Final step is to convert the entire "obj' to plainJS by using toJS(). End result is plainJS "obj"

Deserialize an anonymous JSON array?

I got an anonymous array which I want to deserialize, here the example of the first array object
[
{ "time":"08:55:54",
"date":"2016-05-27",
"timestamp":1464332154807,
"level":3,
"message":"registerResourcePath ('', '/sap/bc/ui5_ui5/ui2/ushell/resources/')",
"details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":"URL prefixes set to:","details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":" (default) : /sap/bc/ui5_ui5/ui2/ushell/resources/","details":"","component":"sap.ui.ModuleSystem"}
]
I tried deserializing using CL_TREX_JSON_SERIALIZER, but it is corrupt and does not work with my JSON, here is why
Then I tried /UI2/CL_JSON, but it needs a "structure" that perfectly fits the object given by the JSON Object. "Structure" means in my case an internal table of objects with the attributes time, date, timestamp, level, messageanddetails. And there was the problem: it does not properly handle references and uses class description to describe the field assigned to the field-symbol. Since I can not have a list of objects but only a list of references to objects that solution also doesn't works.
As a third attempt I tried with the CALL TRANSFORMATION as described by Horst Keller, but with this method I was not able to read in an anonymous array, and here is why
My major points:
I do not want to change the JSON, since that is what I get from sap.ui.log
I prefere to use built-in functionality and not a thirdparty framework
Your problem comes out not from the anonymity of array, but from the awkwardness of SAP JSON (De)serializer, which doesn't respect double quotes, which enclose JSON attributes. The issue is thoroughly described in this answer.
If you don't want to change your JSON on-the-fly, the only way you have is to change CL_TREX_JSON_DESERIALIZER class like this.
/UI5/CL_JSON_PARSER parses JSONs with unknown format.
Note that it's got "for internal use" written on it so many times that you probably should take it seriously and clone its code to fixate it.

Return empty array when transforming xml data to json

I am returning some xml structure as json using the built-in MarkLogic json module. For the most part it does what I expect. However, when an element marked as an array is empty, it returns an empty string instead of an empty array. Here is an example:
xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json"
at "/MarkLogic/json/json.xqy";
let $config := json:config("custom")
return (
map:put( $config, "array-element-names", ("item") ),
json:transform-to-json(<result>
<item>21</item>
<item>22</item>
<item>23</item>
</result>, $config),
json:transform-to-json(<result></result>, $config))
Result:
{"result":{"item":["21", "22", "23"]}}
{"result":""}
I would expect an empty array if there were no items matching in the array-element-name called "item". i.e.
{"result":{"item":[]}}
Is there some way to configure it so it knows the element is required ?
No - it will not create anything that is not there. In your case, what if the XML was more complex. There is no context of 'where' such an element might live - so it could not create it even if it wanted to.
Solution is to repair the content if needed by adding one element - or transforming it into the json-basic namespace - where those elements live inside of of an element noted as an array (which can be empty) - or third, use an XSD to hint to the processor what to do . But that would still need a containing element for the 'array' - and then the items would be minOccurance=0. But if this is the case, then repair and transform into the json/basic namespace is probably nice and simple for your example.

Accessing nested list items in an interpolated string using dot notation in Scala

I'm trying to pass a value via JSON that I am having trouble accessing. We have a data structure (that was obviously not built by me otherwise I would likely understand it) that looks something like this when sent to the browser:
{Foo(Bar(List(Baz(List(G3),w))),G3,None)}
This is sent via a JSON write method, but the originating Scala line looks like:
val hint = Some(s"{$question}") where $question is of type Foo.
I've tried using dot notation to access the list items in ways that I thought would work:
val hint = Some(s"{$question.Bar.Baz})"
val hint = Some(s"{$question.Bar(0).Baz(0)"})
It's the deepest G3 I wanted to strip out and send, but instead the JSON object comes through looking like:
{Foo(Bar(List(Baz(List(G3),w))),G3,None)}.Bar.Baz or
{Foo(Bar(List(Baz(List(G3),w))),G3,None)}.Bar(0).Baz(0)
I must be fundamentally missing something about the data structures involved here.
I think you're just using the wrong syntax. The $ needs to come before the {} and the {} is necessary for any expression more complicated than just a variable name:
s"${question.bar(0).baz(0)}"

Struts:JSON:return multiple objects

Is it possible to return multiple JSON objects in the request header with Struts1? I am presently returning a single JSON objects, however the need now is to return a second data structure. All the client-side processing works perfectly for the single data structure in the single JSON objects, I really do not want to complicate it by putting two hetrogenous data structures in a single return JSON object. tia.
I don't know struts or why you can't return multiple JSON objects, but if you genuinely can't, why don't you return a list of your objects? you can unbox them at the receiving end.
in other words, if you were previously returning obj = {...}, and now need to return that as well as obj2 = {...}, you can return [obj, obj2].
maybe this doesn't solve your problem, but it'll get you around it pretty easily.