How do I get strings from a JSON file? - json

I'm writing a internationalized desktop program written in Vala where a use an extern JSON file to store a list of languages.
I'm using gettext for l10n so if I get the string from the json file and I do something like _(string_var) I could get the translated string. The problem is that I don't know how can I add the string to the pot file using xgettext or some similar tool.
Any idea??

If the tool jq (http://stedolan.github.io/jq/) is an option for you, below might work;
$ curl -s https://raw.githubusercontent.com/chavaone/gnomecat/master/data/languages.json | jq .languages[43].name
"English"

The solution I finally use was to modify the JSON file to use double quoted strings only when I wanted to translate that string. For example:
{
'code' : 'es',
'name' : "Spanish; Castilian",
'pluralform' : 'nplurals=2; plural=(n != 1);',
'default-team-email': 'gnome-es-list#gnome.org'
}
In the previous piece of JSON file the only string I wanted to translate was "Spanish; Castillian". Then in the POTFILES.in, I just use the gettext/quoted type.
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
[encoding: UTF-8]
[type: gettext/quoted]data/languages.json
[type: gettext/quoted]data/plurals.json
[type: gettext/glade]data/ui/appmenu.ui
[...]

Related

How to replace values in a JSON dictionary with their respective shell variables in jq?

I have the following JSON structure:
{
"host1": "$PROJECT1",
"host2": "$PROJECT2",
"host3" : "xyz",
"host4" : "$PROJECT4"
}
And the following environment variables in the shell:
PROJECT1="randomtext1"
PROJECT2="randomtext2"
PROJECT4="randomtext3"
I want to check the values for each key, if they have a "$" character in them, replace them with their respective environment variable(which is already present in the shell) so that my JSON template is rendered with the correct environment variables.
I can use the --args option of jq but there are quite a lot of variables in my actual JSON template that I want to render.
I have been trying the following:
jq 'with_entries(.values as v | env.$v)
Basically making each value as a variable, then updating its value with the variable from the env object but seems like I am missing out on some understanding. Is there a straightforward way of doing this?
EDIT
Thanks to the answers on this question, I was able to achieve my larger goal for a part of which this question was asked
iterating over each value in an object,
checking its value,
if it's a string and starts with the character "$"
use the value to update it with an environment variable of the same name .
if it's an array
use the value to retrieve an environment variable of the same name
split the string with "," as delimiter, which returns an array of strings
Update the value with the array of strings
jq 'with_entries(.value |= (if (type=="array") then (env[.[0][1:]] | split(",")) elif (type=="string" and startswith("$")) then (env[.[1:]]) else . end))'
You need to export the Bash variables to be seen by jq:
export PROJECT1="randomtext1"
export PROJECT2="randomtext2"
export PROJECT4="randomtext3"
Then you can go with:
jq -n 'with_entries((.value | select(startswith("$"))) |= env[.[1:]])'
and get:
{
"host1": "randomtext1",
"host2": "randomtext2",
"host3": "xyz",
"host4": "randomtext3"
}
Exporting a large number of shell variables might not be such a good idea and does not address the problem of array-valued variables. It might therefore be a good idea to think along the lines of printing the variable=value details to a file, and then combining that file with the template. It’s easy to do and examples on the internet abound and probably here on SO as well. You could, for example, use printf like so:
printf "%s\t" ${BASH_VERSINFO[#]}
3 2 57 1
You might also find declare -p helpful.
See also https://github.com/stedolan/jq/wiki/Cookbook#arbitrary-strings-as-template-variables

Oracle SQLcl: Spool to json, only include content in items array?

I'm making a query via Oracle SQLcl. I am spooling into a .json file.
The correct data is presented from the query, but the format is strange.
Starting off as:
SET ENCODING UTF-8
SET SQLFORMAT JSON
SPOOL content.json
Follwed by a query, produces a JSON file as requested.
However, how do I remove the outer structure, meaning this part:
{"results":[{"columns":[{"name":"ID","type":"NUMBER"},
{"name":"LANGUAGE","type":"VARCHAR2"},{"name":"LOCATION","type":"VARCHAR2"},{"name":"NAME","type":"VARCHAR2"}],"items": [
// Here is the actual data I want to see in the file exclusively
]
I only want to spool everything in the items array, not including that key itself.
Is this possible to set as a parameter before querying? Reading the Oracle docs have not yielded any answers, hence asking here.
Thats how I handle this.
After output to some file, I use jq command to recreate the file with only the items
ssh cat file.json | jq --compact-output --raw-output '.results[0].items' > items.json
`
Using this library = https://stedolan.github.io/jq/

How to escape JSON string for CSV parsing?

A bit of an odd question perhaps.
I'm trying to Store a JSON string appropriately in a CSV column as a string. It works OK when generating the CSV file, however parsing the CSV file with the JSON in it is a problem.
I've tried "{"prop": "Val"...}", "{""prop"": ""Val""...}", "{\"prop\": \"Val\"...}", "{\""prop\"": \""Val\""...}"
However none of them parse well at all.
Please help!
The correct answer here is to double quote the JSON string so this:
{ "a": 10 }
converts into this:
"{ ""a"": 10 }"
You can use the following replace logic to escape your JSON string:
`"${YOUR_JSON_STR.replace(/\"/g, '""')}"`

Ways to parse JSON using KornShell

I have a working code for parsing a JSON output using KornShell by treating it as a string of characters. The issue I have is that the vendor keeps changing the position of the field that I am intersted in. I understand in JSON, we can parse it by key-value pairs.
Is there something out there that can do this? I am intersted in a specific field and I would like to use it to run the checks on the status of another RESTAPI call.
My sample json output is like this:
JSONDATA value :
{
"status": "success",
"job-execution-id": 396805,
"job-execution-user": "flexapp",
"job-execution-trigger": "RESTAPI"
}
I would need the job-execution-id value to monitor this job through the rest of the script.
I am using the following command to parse it:
RUNJOB=$(print ${DATA} |cut -f3 -d':'|cut -f1 -d','| tr -d [:blank:]) >> ${LOGDIR}/${LOGFILE}
The problem with this is, it is field delimited by :. The field position has been known to be changed by the vendors during releases.
So I am trying to see if I can use a utility out there that would always give me the key-value pair of "job-execution-id": 396805, no matter where it is in the json output.
I started looking at jsawk, and it requires the js interpreter to be installed on our machines which I don't want. Any hint on how to go about finding which RPM that I need to solve it?
I am using RHEL5.5.
Any help is greatly appreciated.
The ast-open project has libdss (and a dss wrapper) which supposedly could be used with ksh. Documentation is sparse and is limited to a few messages on the ast-user mailing list.
The regression tests for libdss contain some json and xml examples.
I'll try to find more info.
Python is included by default with CentOS so one thing you could do is pass your JSON string to a Python script and use Python's JSON parser. You can then grab the value written out by the script. An example you could modify to meet your needs is below.
Note that by specifying other dictionary keys in the Python script you can get any of the values you need without having to worry about the order changing.
Python script:
#get_job_execution_id.py
# The try/except is because you'll probably have Python 2.4 on CentOS 5.5,
# and the straight "import json" statement won't work unless you have Python 2.6+.
try:
import json
except:
import simplejson as json
import sys
json_data = sys.argv[1]
data = json.loads(json_data)
job_execution_id = data['job-execution-id']
sys.stdout.write(str(job_execution_id))
Kornshell script that executes it:
#get_job_execution_id.sh
#!/bin/ksh
JSON_DATA='{"status":"success","job-execution-id":396805,"job-execution-user":"flexapp","job-execution-trigger":"RESTAPI"}'
EXECUTION_ID=`python get_execution_id.py "$JSON_DATA"`
echo $EXECUTION_ID

Can a JSON value contain a multiline string

I am writing a JSON file which would be read by a Java program. The fragment is as follows...
{
"testCases" :
{
"case.1" :
{
"scenario" : "this the case 1.",
"result" : "this is a very long line which is not easily readble.
so i would like to write it in multiple lines.
but, i do NOT require any new lines in the output.
I need to split the string value in this input file only.
such that I don't require to slide the horizontal scroll again and again while verifying the correctness of the statements.
the prev line, I have shown, without splitting just to give a feel of my problem"
}
}
}
Per the specification, the JSON grammar's char production can take the following values:
any-Unicode-character-except-"-or-\-or-control-character
\"
\\
\/
\b
\f
\n
\r
\t
\u four-hex-digits
Newlines are "control characters", so no, you may not have a literal newline within your string. However, you may encode it using whatever combination of \n and \r you require.
The JSONLint tool confirms that your JSON is invalid.
And, if you want to write newlines inside your JSON syntax without actually including newlines in the data, then you're doubly out of luck. While JSON is intended to be human-friendly to a degree, it is still data and you're trying to apply arbitrary formatting to that data. That is absolutely not what JSON is about.
I'm not sure of your exact requirement but one possible solution to improve 'readability' is to store it as an array.
{
"testCases" :
{
"case.1" :
{
"scenario" : "this the case 1.",
"result" : ["this is a very long line which is not easily readble.",
"so i would like to write it in multiple lines.",
"but, i do NOT require any new lines in the output."]
}
}
}
}
Then join it back as the need arrives with
result.join(" ")
Not pretty good solution, but you can try the hjson tool. It allows you to write text multi-lined in editor and then converts it to the proper valid JSON format.
Note: it adds '\n' characters for the new lines, but you can simply delete them in any text editor with the "Replace all.." function.
I believe it depends on what json interpreter you're using... in plain javascript you could use line terminators
{
"testCases" :
{
"case.1" :
{
"scenario" : "this the case 1.",
"result" : "this is a very long line which is not easily readble. \
so i would like to write it in multiple lines. \
but, i do NOT require any new lines in the output."
}
}
}
As I could understand the question is not about how pass a string with control symbols using json but how to store and restore json in file where you can split a string with editor control symbols.
If you want to store multiline string in a file then your file will not store the valid json object. But if you use your json files in your program only, then you can store the data as you wanted and remove all newlines from file manually each time you load it to your program and then pass to json parser.
Or, alternatively, which would be better, you can have your json data source files where you edit a sting as you want and then remove all new lines with some utility to the valid json file which your program will use.