I was trying to find ways to get an attribute path from a JSON.
However, I only see a path extractor if the path is known and not vice verca.
Here is an example:
I'm looking to get the 'numComments' attribute path from the following JSON (the path is: inpage.header.numComments).
{
"inpage": {
"conversation": {
"completeEmailRegistration": {
"button": "重新寄出确认电邮",
"succesMessage": {
"first": "确认电邮已经寄到",
"second": "请检查你的邮箱。"
},
"text": "请检查您的邮箱以完成账号登记手续。"
},
"loadMoreReplies": "Show More Comments",
"loadMoreReviews": "显示更多评价",
"loadReplies": "显示评论",
"replyTyping": "{{value}}正在回复",
"showAllMessages": "显示所有{{messagesCount}}回复",
"showMoreMessagesErrorMessage": "无法得到更多回复",
"sortMenu": {
"best": "最好",
"newest": "最新",
"oldest": "最旧",
"social": "社交",
"sortBy": "排序方式"
},
"viewReplies": "显示回复",
"newMessagesMobile_0": "{{numOfComments}} 条新评论",
"newMessages_0": "查看 {{numOfComments}} 条新评论",
"showMoreMessagesOnlyNumber_0": "{{messagesCount}} 个回复",
"showMoreMessages_0": "再显示 {{messagesCount}} 个回复",
"showPreviousMessages_0": "显示{{messagesCount}}个以前的回复",
"typingUsers_0": "{{count}} 人在输入"
},
"header": {
"comments": "评论",
"commentsCount": {
"more": "{{messagesCount}}帖子",
"one": "1个帖子"
},
"conversation": "对话",
"explore": "探索",
"starsRating": "评价",
"subheader": {
"communityGuidelines": "社区准则",
"gotIt": "明白了",
"powered-by": "技术支持:",
"text": "阅读我们的"
},
"viewing": "{{viewersCount}} 人正在观看",
"shortNumComments": "({{messagesCount}})",
"shortNumComments_plural": "({{messagesCount}})",
"numComments": "{{messagesCount}}个评论",
"numComments_plural": "{{messagesCount}}个评论",
"numPosts": "{{messagesCount}}个帖子",
"numPosts_plural": "{{messagesCount}}个帖子"
}
}
Any suggestions?
install extension for chrome: JSON Viewer Pro
click to open extension:
click JSON input
copy and paste your json in the window opened
click parse json
click the attribute for which you want its path
icon will appear from where can copy path of the attribute
Note: for this your JSON must be a verified and correct one, i see bunch of {, } inside data values. this may cause and invalid json error.
Related
given this node in a json response:
{
"name": "RFM912Feilkode",
"valueCodeableConcept": {
"coding": [
{
"system": "http://xxx/error-code",
"code": "0"
}
],
"text": "OK"
}
I want to verify that the text "OK" is present in Gatling using Scala syntax.
Something (pseudo code ish):
.check(jsonPath("$..valueCodeableConcept.text").is("OK"))
but this does not work. Any tips on how to "hit" the OK value and check if it exists?
Your json isn't valid. Missing curly bracket.
I tried this and all works fine:
.check(jsonPath("$.valueCodeableConcept.text").is("OK"))
If you want to extract some json based on other elements in the json (what you seem to be getting at in the comments on other answers), then you can use filters in the jsonPath like
$.[?(#.name=="RFM912Feilkode")].valueCodeableConcept.text
which will get you the text element from valueCodeableConcept where the associated name is RFM912Feilkode
Im trying to extracting json objects and store it to hdfs. I'm targeting message attribute which is a6,b6,c6,d6,e6
json sample
{
"#timestamp":"2020-07-06T07:35:29.047Z",
"#metadata":{
"beat":"filebeat",
"type":"_doc",
"version":"7.7.1"
},
"log":{
"offset":91,
"file":{
"path":"C:\\Program Files\\Filebeat\\test-kafka\\test_csv.csv"
}
},
"message":"a6,b6,c6,d6,e6",
"input":{
"type":"log"
},
"ecs":{
"version":"1.5.0"
},
"host":{
"name":"host"
},
"agent":{
"version":"7.7.1",
"type":"filebeat",
"ephemeral_id":"0b4a288f-f7ac-4db9-835e-60ca07a45fff",
"hostname":"host",
"id":"5e2fec03-bbdc-4f91-acc9-4ab36c7268db"
}
}
GenerateFlowFile properties
JsonEvaluatePath properties
but problem JsonEvaluatePath not working as i expected, i thought it will extracting only message attribute.
hadoop#ambari:~$ hdfs dfs -cat /user/test/5a422f02-9074-4384-a3c9-f3e3ce7c2e40
{
"#timestamp":"2020-07-06T07:35:29.047Z",
"#metadata":{
"beat":"filebeat",
"type":"_doc",
"version":"7.7.1"
},
"log":{
"offset":91,
"file":{
"path":"C:\\Program Files\\Filebeat\\test-kafka\\test_csv.csv"
}
},
"message":"a6,b6,c6,d6,e6",
"input":{
"type":"log"
},
"ecs":{
"version":"1.5.0"
},
"host":{
"name":"host"
},
"agent":{
"version":"7.7.1",
"type":"filebeat",
"ephemeral_id":"0b4a288f-f7ac-4db9-835e-60ca07a45fff",
"hostname":"host",
"id":"5e2fec03-bbdc-4f91-acc9-4ab36c7268db"
}
}
Am i missing something?
Since you used EvaluateJsonPath with destination set as flow file attributes, it extracted message into a flow file attribute and the content of the flow file is still the same as it was before. You would need to use another processor like AttributesToJson before PutHDFS to rewrite the flow file content with the attributes you want. An alternative might be to set EvaluateJsonPath destination to flow file content, but I'm not sure if that produces valid json.
I'm trying to set a data model inside my manifest.json within my webapp.
Im using sapui5 and I'm quite new to it.
the resource I'm getting from my api is a jsonObject but somehow the model is not initiated properly. I checked the model with console.log() and it's empty.
when I do the same with an jsonArray it is working.
I should mention that I use a mockserver.js
Here is the code I'm using.
manifest.json:
"sap.app": {
...
"dataSources": {
"invoiceRemote": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "localService/metadata.xml"
}
}
}
}
...
"sap.ui5": {
...
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "MyInboxUI5.i18n.i18n"
}
},
"invoice": {
"dataSource": "invoiceRemote"
}
...
and with JsonObject I mean a .json of this style:
{
"field1": value1,
"field2": value2,
"field3": [
{
"field4": value4,
"field5": value5
},
{
"field6": value6,
"field7": value7
} ]
}
(that's the one not working)
and with JsonArray I meant
[
{
"field4": value4,
"field5": value5
},
{
"field6": value6,
"field7": value7
}
]
(This one is working)
To check my model I used the simple console.log()
Component.js (part of it)
init: function() {
console.log(this.getModel("invoice"));
UIComponent.prototype.init.apply(this, arguments);
this.getRouter().initialize();
}
I did not post the mockserver.js or metadata.xml because I'm not sure it's that relevant and they take a lot of space.
So does anyone know if there is a way to load the model of a JsonObject inside the manifest.json?
I'm aware that there are other possibilities to load the model that do work, but I'm only interestet in that specific case.
Without having additional information about what you actually try to achieve it's hard to point you into the right direction.
The important information is that you are using an ODataModel + a mockserver. Thanks to the mockserver you can easily mock your data for the entities of your OData service - actually you can even mock much more...
Basically, the mock data files need to contain flat lists. In other words, you have always an array of flat objects. The mockserver gets the data (i.e. entities by id) from exactly from these files. The mockserver can only find the files if they have the correct name (see walkthrough tutorial for details). As a rule of thumb "1 file contains data for one entity/entityset".
There is no way to model JsonObjects inside the manifest. What you can do is mocking your mockserver (i.e. by reading json files manually), that works perfectly (the explored app has some examples). However, don't forget we are talking about OData!
Hint: your data looks like a tree, so I guess you want to model a tree structure. If you check the explored app there are a few examples for OData Tree binding and there I'm using the mockserver as well. Maybe that helps...
If JSON arrays are used in a SenseNet settings object, they are not accessible via the OData API.
For example, consider the following SenseNet settings object, which comes installed at Root/System/Settings/Portal.settings by default:
{
ClientCacheHeaders: [
{ ContentType: "PreviewImage", MaxAge: 1 },
{ Extension: "jpeg", MaxAge: 604800 },
{ Extension: "gif", MaxAge: 604800 },
{ Extension: "jpg", MaxAge: 604800 },
{ Extension: "png", MaxAge: 604800 },
{ Extension: "swf", MaxAge: 604800 },
{ Extension: "css", MaxAge: 600 },
{ Extension: "js", MaxAge: 600 }
],
UploadFileExtensions: {
"jpg": "Image",
"jpeg": "Image",
"gif": "Image",
"png": "Image",
"bmp": "Image",
"svg": "Image",
"svgz": "Image",
"tif": "Image",
"tiff": "Image",
"xaml": "WorkflowDefinition",
"DefaultContentType": "File"
},
BinaryHandlerClientCacheMaxAge: 600,
PermittedAppsWithoutOpenPermission: "Details"
}
When viewing this object through the OData API, the ClientCacheHeaders field is not included:
{
"d": {
"UploadFileExtensions.jpg": "Image",
"UploadFileExtensions.jpeg": "Image",
"UploadFileExtensions.gif": "Image",
"UploadFileExtensions.png": "Image",
"UploadFileExtensions.bmp": "Image",
"UploadFileExtensions.svg": "Image",
"UploadFileExtensions.svgz": "Image",
"UploadFileExtensions.tif": "Image",
"UploadFileExtensions.tiff": "Image",
"UploadFileExtensions.xaml": "WorkflowDefinition",
"UploadFileExtensions.DefaultContentType": "File",
"BinaryHandlerClientCacheMaxAge": 600,
"PermittedAppsWithoutOpenPermission": "Details",
}
}
If you search specifically for the ClientCacheHeaders field using the following query:
Odata.svc/Root/System/Settings('Portal.settings')?&metadata=no&$select=ClientCacheHeaders
the API returns null:
{
"d": {
"ClientCacheHeaders": null
}
}
I know that JSON arrays are allowed in settings files because the above example is referenced in the SenseNet wiki page describing settings usage.
Am I performing my OData query incorrectly, or is this some sort of parsing bug in the SenseNet API?
Here's an implementation of the custom OData function suggested by Miklos. Once this is done, you have to register the OData call as described here.
public static class OData
{
[ODataFunction]
public static string GetMySettings(Content content)
{
var retstr = "";
try
{
var settingsFile = Settings.GetSettingsByName<Settings>("MySettings", content.Path);
var node = Node.LoadNode(settingsFile.Path) as Settings;
var bindata = node.GetBinary("Binary");
using (var sr = bindata.GetStream())
using (var tr = new System.IO.StreamReader(sr))
retstr = tr.ReadToEnd();
}
catch (Exception e)
{
SnLog.WriteException(e);
}
return retstr;
}
}
This is a limitation of the current dynamic json field conversion behind the odata api. It actually converts these setting json properties to sensenet fields, so what you see in the odata response is not the actual settings json, but only the fragments that can be converted to sensenet fields (for the curious: it happens in the JsonDynamicFieldHelper class, BuildDynamicFieldMetadata method).
And unfortunately there is no built-in field type in sensenet for handling json arrays, it is not possible to convert a json array to a field value, this is why the system skips it.
Workaround 1
Get the raw settings json in javascript in two steps. The following request gives you the binary field's direct url:
/odata.svc/Root/System/Settings('Portal.settings')?&metadata=no&$select=Binary
...something like this:
/binaryhandler.ashx?nodeid=1084&propertyname=Binary&checksum=1344168
...and if you load that, you'll get the full raw json, including the array.
Please note: Settings are not accessible to visitors by
default, for a reason: they may contain sensitive information. So if
you want to let your users access settings directly (the way you tried
or the way described in the first workaround above), you'll have to
give open permission for the necessary user groups on those setting
files. This is not the case with the second workaround.
Workaround 2
Create a custom odata action that returns settings in a format of your choice from the server. This is a better solution, because this way you control which parts of a setting file is actually accessible to the client.
I am using Restheart and MongoDB and also new in these, I have to write aggregation in MongoDb. I written aggregation in mongoDb with $match.
Here Sample Code:
{
"aggrs": [{
"type": "pipeline",
"uri": "aggregation_by_time",
"stages": [{
"_$match": {
"bus::destination": {
"_$in": {
"_$var": "stand"
}
},
"bus::eta": {
"_$gte": {
"_$var": "fromDate"
},
"_$lte": {
"_$var": "toDate"
}
},
"tickets": {
"_$eq": {
"_$var": "isConfirmedTravel"
}
}
}
}]
}]
}
Here Sample Access Url:
http://..xyz../_aggrs/aggregation_by_time?avars={"stand":["A","B","C","D","E","F"]}
When I access this url then it is not working, displaying some error.
Error:
{"http status code":400,"http status description":"Bad
Request","message":"error executing aggreation pipeline: variable
isConfirmedTravel not bound"}
When I access below url Then it will work.
http://..xyz../_aggrs/aggregation_by_time?avars={"stand":["A","B","C","D","E","F"],"isConfirmedTravel":"true"}
So I want to make optional $match, Like if I don't mention as a parmater "isConfirmedTravel" in url, then it should work. And If I want to send as parameter "isConfirmedTravel" in url then It should also work. But In my case If put field in $match then you should have to mention in url. Thats why I want to set optional "isConfirmedTravel":"true" field. If I call then it should work and if I will not call then url should be work.