Bitly, Json, and C# - json

I'm working on something that involved using the Bit.ly API, and allow the user to select theformat (Text, XML, Json) the text & XML are completed. This is the Json result that is returned when you shorten a URL:
{
"status_code": 200,
"status_txt": "OK",
"data":
{
"long_url": "http:\/\/panel.aspnix.com\/Default.aspx?pid={Removed}",
"url": "http:\/\/rlm.cc\/gtYUEd",
"hash": "gtYUEd",
"global_hash": "evz3Za",
"new_hash": 0
}
}
And this C# code works just fine to parse it and get the short URL:
var serializer2 = new JavaScriptSerializer();
var values2 = serializer2.Deserialize<IDictionary<string, object>>(json);
var results2 = values2["data"] as IDictionary<string, object>;
var shortUrl2 = results2["url"];
expandedUrl = results2["url"].ToString();
return results2["url"].ToString();
Now here's the Json sent back when expanding a URL:
{
"status_code": 200,
"status_txt": "OK",
"data":
{
"expand":
[
{
"short_url": "http:\/\/rlm.cc\/gtYUEd",
"long_url": "http:\/\/panel.aspnix.com\/Default.aspx?pid={Removed}",
"user_hash": "gtYUEd",
"global_hash": "evz3Za"
}
]
}
}
Ad that's where my problem begins, how can I change my current C# to be able to handle both scenarios, because as you can see their vastly different from each other. Any ideas?

I usually use Json.NET to cherrypick values out of JSON documents. The syntax is very concise. If you reference NewtonSoft.Json.dll and use Newtonsoft.Json.Linq, you can write the following:
var job = JObject.Parse(jsonString);
if (job["data"]["expand"] == null)
{
Console.WriteLine((string)job["data"]["url"]);
}
else
{
Console.WriteLine((string)job["data"]["expand"][0]["long_url"]);
}
If jsonString is:
string jsonString = #"{""status_code"": 200, ""status_txt"": ""OK"", ""data"": {""long_url"": ""http:\/\/panel.aspnix.com\/Default.aspx?pid={Removed}"", ""url"": ""http:\/\/rlm.cc\/gtYUEd"", ""hash"": ""gtYUEd"", ""global_hash"": ""evz3Za"", ""new_hash"": 0 }}";
the routine will display http://rlm.cc/gtYUEd.
If jsonString is:
string jsonString = #"{""status_code"": 200, ""status_txt"": ""OK"", ""data"": { ""expand"": [ { ""short_url"": ""http:\/\/rlm.cc\/gtYUEd"", ""long_url"": ""http:\/\/panel.aspnix.com\/Default.aspx?pid={Removed}"", ""user_hash"": ""gtYUEd"", ""global_hash"": ""evz3Za"" } ] } }";
the routine will display http://panel.aspnix.com/Default.aspx?pid={Removed}.

Not sure I got your problem. Why aren't you testing, if you got a shortening result or a expanding result? Since they are different, this could easily be done via simple 'if ()' statements:
if (results2.ContainsKey("expand")) {
// handle the expand part
} else {
// handle the shorten part
}

Assuming that the provider is consistent with which form it sends, do you need to have code that handles both? It should be direct to handle each individually.
If you can't know ahead of time which format you will get back, you can do the following:
if (results2.ContainsKey("expand"))
{
//Second example
}
else
{
//First example
}

Related

Unable to parse JSON data due to errors or undefined data

I apologize if this seems similar to other questions asked but I have not been able to find any posts that have resolved this issue for me. Basically, I am getting a JSON object and I am trying to parse it but I can't parse it correctly. Mainly the WordDetails section that I am getting from a Word API. I am able to get everything outside the results section under WordDetails. Basically, when I get to results, I am not able to parse it correctly. Below is an example of the format.
{
"LastIndex": 133,
"SRDWords": [
{
"Domain": {
"URL": "abactinal.com",
"Available": true
},
"WordDetails": "{\"word\":\"abactinal\",\"results\":[{\"definition\":\"(of radiate animals) located on the surface or end opposite to that on which the mouth is situated\",\"partOfSpeech\":null,\"antonyms\":[\"actinal\"]}],\"syllables\":{\"count\":4,\"list\":[\"ab\",\"ac\",\"ti\",\"nal\"]}}"
},
{
"Domain": {
"URL": "aaronical.com",
"Available": true
},
"WordDetails": "{\"word\":\"aaronical\",\"syllables\":{\"count\":4,\"list\":[\"aa\",\"ron\",\"i\",\"cal\"]},\"pronunciation\":{\"all\":\"ɜ'rɑnɪkəl\"}}"
},
...
Here is my code below. Basically, I am getting to the results section of WordDetails but if I try to parse the results section it fails and if I try object.entries on it, it will not return a response according to the alert messages I used. I know there must be a better way but not sure what. Most articles say just JSON.parse then map it but that does not work. Any help would be appreciated!
data.Words.map(word => {
//get data
for (let [key, value] of Object.entries(word)) {
if (key === "Domain") {
url = value.URL;
availability = value.Available;
} else if (key.trim() === "WordDetails") {
alert("value " + value);
wDetails = JSON.parse(value);
for (let [key2, value2] of Object.entries(wDetails)) {
if (key2 === "word") {
//store word
} else if (key2.toString().trim() === "results") {
let test = JSON.parse(value2);
test = Object.entries(value2);
test.map(t => {
alert(t.definition);
});
}
}
}
}
});
You did JSON.parse above, no need to parse value2 again.
And value for results is an array, so no need for Object.entries.
...
} else if (key2.toString().trim() === 'results') {
let test = JSON.parse(value2); // this should be remove
test = Object.entries(value2); // this should be remove, value2 should be an array
// map value2 directly
value2.map(t => {
alert(t.definition);
});
}
...

How to access data inside a complex JSON object in Dart?

I use a WebSocket to communicate to a server in my Flutter app. Let's say I receive a JSON object trough the WebSocket :
{
"action": "getProduct",
"cbackid": 1521474231306,
"datas": {
"product": {
"Actif": 1,
"AfficheQte": 0,
"Article": "6"
},
"result": "success"
},
"deviceID": "4340a8fdc126bb59"
}
I have no idea what the content of datas will be until I read the action, and even then, it's not guaranteed to be the same every time. One example of a changing action/datas is when the product doesn't exist.
I can parse it in a Map<String, Object>, but then, how do I access what's inside the Object?
What's the correct way to read this data?
Not sure what the question is about, but you can check the type of the values and then continue accordingly
if(json['action'] == 'getProduct') {
var datas = json['datas'];
if(datas is List) {
var items = datas as List;
for(var item in items) {
print('list item: $item');
}
} else if (datas is Map) {
var items = datas as Map;
for(var key in items.keys) {
print('map item: $key, ${items[key]}');
}
} else if(datas is String) {
print('datas: $datas');
} // ... similar for all other possible types like `int`, `double`, `bool`, ...
}
You also can make that recursive to check list or map values if they are String, ...

extract-document-data comes as xml string element in json output

I am trying to enrich my search results with some elements taken from the "matching" documents, using the query option "extract-document-data" like
<options xmlns="http://marklogic.com/appservices/search">
<extract-document-data selected="include">
<extract-path>/language-version/language-version-canonical-model/title</extract-path>
<extract-path>/language-version/language-version-canonical-model/language</extract-path>
</extract-document-data>
(...)
</options>
When I run the search and I ask for Json output (using the header Accept: application/json) I get as mix of json and "strinxml" as a result:
{
"snippet-format": "snippet",
"total": 564,
"start": 1,
"page-length": 10,
"selected": "include",
"results": [
{
"index": 1,
"uri": "ENV/CHEM/NANO(2015)22/ANN5/2",
"path": "fn:doc(\"ENV/CHEM/NANO(2015)22/ANN5/2\")",
(...)
"matches": [
{
"path": "fn:doc(\"ENV/CHEM/NANO(2015)22/ANN5/2\")/ns2:language-version/ns2:language-version-raw-data/*:document/*:page[22]",
(...)
}
],
"extracted": {
"kind": "element",
"content": [
"<language>En</language>",
"<title>ZINC OXIDE DOSSIERANNEX 5</title>",
"<reference>ENV/CHEM/NANO(2015)22/ANN5</reference>",
"<classification>2</classification>",
"<modificationDate>2015-04-16T00:00:00.000+02:00</modificationDate>",
"<subject label_en=\"media\" >media</subject>",
"<subject label_en=\"fish\" ">fish</subject>",
]
}
},
The problem here is with the "extracted" part, as you can see, it looks like the xml elements have been simply copied as string, when I would really expect them to be converted to json.
Does anybody have an idea about this problem?
MarkLogic won’t convert content. So, XML will remain XML when asking for JSON formatted search response. And since you can't really embed XML inside JSON, it gets serialized as a string.
You could try applying a REST transform on your search results, and use something like json:transform-to-json (probably with the custom config) to convert those on the fly. For instance something like this Server-side JavaScript transform:
/* jshint node:true,esnext:true */
/* global xdmp */
var json = require('/MarkLogic/json/json.xqy');
var config = json.config('custom');
function toJson(context, params, content) {
'use strict';
var response = content.toObject();
if (response.results) {
response.results.map(function(result) {
if (result.extracted && result.extracted.content) {
result.extracted.content.map(function(content, index) {
if (content.match(/^</) && !content.match(/^<!/)) {
result.extracted.content[index] = json.transformToJson(xdmp.unquote(content), config);
}
});
}
});
}
return response;
}
exports.transform = toJson;
You could also convert client-side of course.
HTH!
If you're using the Java Client API you can use the correct handle for each result to read the extracted items (see ExtractedResult and ExtractedItem):
SearchHandle results = queryManager.search(query, new SearchHandle());
for (MatchDocumentSummary summary : results.getMatchResults()) {
ExtractedResult extracted = summary.getExtracted();
// here we check to see if this result is XML format, and if so
// we use org.w3c.dom.Document
if ( Format.XML == summary.getFormat() ) {
for (ExtractedItem item : extracted) {
Document extractItem = item.getAs(new DOMHandle()).get();
...
}
// or if the result is JSON we could choose a different handle
} else if ( Format.JSON == summary.getFormat() ) {
for (ExtractedItem item : extracted) {
JsonNode extractItem = item.getAs(JsonNode.class);
...
}
}
}

Taking out a text from a String as a Key from Json

I need to take out 1000 from this Key-Value Pair in node Js
"msg":"amamm : ErrorResponse {\"abcd1\":{\"Status\":\"E\",\"rem\":{\"Code\":\"1000\",\"message\":\"Unable to access your information at this time.(1000)\"}}}"
The JSON what you have posted is invalid. May be your JSON should be like the following:
var json = {
"msg": {
"amm": {
"ErrorResponse": {
"abcd1": {
"Status": "E",
"rem": {
"Code": "1000",
"message": "Unabletoaccessyourinformationatthistime.(1000)"
}
}
}
}
}
}
Then in node.js you have get the value using dot notation like as follows:
json.msg.amm.ErrorResponse.abcd1.rem.code
Will give you the value 1000
Assuming you can get the string
amamm : ErrorResponse {\"abcd1\":{\"Status\":\"E\",\"rem\":{\"Code\":\"1000\",\"message\":\"Unable to access your information at this time.(1000)\"}}}
by doing err.msg
You can get the json and then get the string you want. I copied the content of the msg into a variable str just to test the regex
var re = /\{.*?\}$/;
var str = 'amamm : ErrorResponse {\"abcd1\":{\"Status\":\"E\",\"rem\":{\"Code\":\"1000\",\"message\":\"Unable to access your information at this time.(1000)\"}}}';
var m;
if ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
var content = JSON.parse(m[0]);
console.log(content);
console.log(content.abcd1.rem.Code);
}
Here's a working example: http://jsfiddle.net/sger1gk6/

JSON ignore fields outside data maps

I am getting some response :
var xxx_api = { "user" : {
"name":"satishpandey",
"sites":[
{
"name":"SEO Product",
"url":"http://www.xxx.com/"
} ]
}};
I want to exclude all the string those are outside json data.
var xxx_api and ; are needs to be excluded.
Is there anything in jackson to exclude these strings?
Assuming you are using this in a get/post (restful-like) method, maybe that has to do with the header of the webservice method you are using. I am using REST and I am able to specify the format I want to receive the json input like this
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON)
public Response myMethod(#FormParam("post") String jsonInput){
// ...
// use jsonInput
mapper.readValue(jsonInput, ...);
// ...
}
Considering this, I guess the input written to the var jsonInput (in the header) would be
{ "user" : {
"name":"satishpandey",
"sites":[
{
"name":"SEO Product",
"url":"http://www.xxx.com/"
} ]
}};
I didn't find any solutions for it in jackson. Now I am using String.substring() method for getting the desired results.
StringBuilder stringBuilder = new StringBuilder(jsonString);
stringBuilder.replace(0, stringBuilder.indexOf("{"), "");
stringBuilder.replace(stringBuilder.lastIndexOf("}") + 1, stringBuilder.length(), "");
It is working perfectly for me.