jbj v7.1.4
JBJ : transform Json By Json
A new way to transform JSON object with a JSON stylesheet. It's like XSL/XML but only with JSON.
Try it online !
http://inist-cnrs.github.io/jbj-playground/
Contributors
Installation
With npm do:
$ npm install jbj
Tests
Use mocha to run the tests.
$ npm install
$ npm test
Documentation
API
render(stylesheet : Object, input : Mixed, callback : Function) : None
Render input
with stylesheet
.
var JBJ = require('jbj'),
JBJ.render({ "truncate" : 3 }, "1234", function(err, out) {
console.log(out);
});
// Output : 123
Variables
Variable can be set using $
plus a dot notation path.
The set value can only be a JBJ expression (not a JSON literal).
Input:
{
"a": {
"b": {
"c": 1
},
"d": "Second"
}
}
Stylesheet:
{
"$x" : {
"get": "a.b.c"
},
"$y.y1.y2" : {
"get": "a.d"
}
}
Output:
{
"a": {
"b": {
"c": 1
},
"d": "Second"
},
"x": 1,
"y": {
"y1": {
"y2": "Second"
}
}
}
inject(stylesheet : Object, input : Mixed, callback : Function) : None
Alertative mode to use JBJ actions. You can inject in stylesheet
the input
.
Injections are identified by a prefix and suffix in the key.
The prefix and the suffix are the less-than sign <
.
Prefix inject the result of a JBJ action in the current scope.
Suffix inject the result of a JBJ render in the current key.
var JBJ = require('jbj'),
JBJ.render({ "<truncate" : 3 }, "1234", function(err, out) {
console.log(out);
});
// Output : 123
prefix
var input = {
key : "hello"
}
var stylesheet = {
"obj" : {
"<get" : "key",
upcase: true
}
};
// output : { obj : "HELLO" }
suffix
var input = {
key : "hello"
}
var stylesheet = {
"obj" : {
"keyword<" : {
get : "key",
upcase: true
}
}
};
// output : { obj : { keyword : "HELLO" } }
register(protocol : String, callback : Function) : None
Add a function to fetch data for a specific protocol
JBJ.register('http:', function request(urlObj, callback) {
var buf = ''
, req = require('http').get(urlObj, function(res) {
if (res.statusCode !== 200) {
return callback(new Error('HTTP Error ' + res.statusCode));
}
res.setEncoding('utf8');
res.on('data', function (chunk) {
buf += chunk.toString();
});
res.on('error', callback);
res.on('end', function() {
callback(null, buf);
});
});
req.on('error', callback);
});
getActions() : Array
List all available actions.
var JBJ = require('jbj'),
console.log(JBJ.getActions());
// Output : ['get', 'set', 'expect' ...]
getFilter(filterName : String) : Function
Get the statement function for an action name.
var JBJ = require('jbj'),
var func = JBJ.getFilter('append');
func('Hello', 'World' , function(err, output) {
console.log(output)
})
// Output : HelloWorld
use(module: Function) : None
Adding filters/actions for external module. see the avaible modules here : https://www.npmjs.com/browse/keyword/jbj
var JBJ = require('jbj'),
JBJ.use(require('jbj-numerical'));
JBJ.use(require('jbj-ist'));
JBJ.use(require('jbj-rdfa'));
Warning: the method has change since v4.0
Actions
A stylesheet is a JSON object where each key is an action. The actions are divided into modules (since v4.0):
- basics: all the basic actions for JBJ (debug, default, extend, set, get, add, expect, foreach, select, cast, mask, trim, required, assert, breakif, inject, render, compute)
- ejs: mainly the filters borrowed from EJS (first, last, capitalize, downcase, upcase, slug, sort, sort_by, size, max, min, plus, minus, times, dividedBy, join, truncate, shift, truncateWords, replace, prepend, append, reverse, flatten, deduplicate, remove, sum, slug)
- parse: file format conversion, through parsing (csv, parseCSV, parseCSVFile, json, parseJSON, xml, parseXML)
- template: template, templateURL
- array: complex actions implying arrays (mapping, mappingVar, zip, array2object, arrays2objects, coalesce, substring, getindex, getindexvar)
- rdfa: generate HTML+RDFa from a JSON-LD (getJsonLdField, style, class, tag, toHtml)
- nlp: natural language processing (anglicize, countCharacters, countWords, tokenize, metaphone)
- numerical: numerical text processing (floatprint, loselose, pearson, sdbm, fnv1a, murmur3, distincter, reseter)
- jsonld: facilitate the generation of JSON-LD from JSON (context, jsonld)
The modules you can use by defaults are basics
and ejs
.
To use another module, first install it via npm:
$ npm install jbj-array
then declare its use via:
JBJ.use(require('jbj-array'));
Note:
basics
andejs
modules are distributed with thejbj
package, and used by default: you can use their actions without any further declaration. However,parse
,template
, andarray
, which were parts of the pre-3.0 versions of JBJ are now separate packages (simply addjbj-
before the modules names to get their matching packages).
set: value
- module: basics
Set value and ignore input
var stylesheet1 = {
"set": "value"
};
var stylesheet2 = {
"set": ["value", "value", "value"]
};
var stylesheet3 = {
"set": {
"a": 1,
"b": 2
}
};
get: path | path,path, ...
- module: basics
- aliases : find , path
Get value in input with some paths (with dot notation style)
var stylesheet1 = {
"set": {
"a" : {
"b" : {
"c" : "Yo"
}
}
},
"get": "a.b.c"
};
// output : Yo
var stylesheet2 = {
"set" : {
"a" : {
"b" : 1,
"c" : 2,
"d" : 3
}
},
"get": ["a.b", "a.c", "a.d"]
};
// output : [1, 2, 3]
default: value
- module: basics
Fix value if input is not set
var stylesheet = {
var stylesheet = {
"default": "value"
};
};
fetch
- module: basics
- aliases : fetchURL, $?
Stylesheet can contain a reference to data source. Source can be a file or an URL. By default, only the file: protocol is supported. Add your own protocol with register
var stylesheet_1 = {
"fetch" : "https://raw.githubusercontent.com/castorjs/node-jbj/master/package.json",
"$name" : {
"upcase": true
},
"$main": {
"upcase": true
}
};
var stylesheet_2 = {
"$name" : {
"fetch" : "file://" + path.resolve(__dirname, '../dataset/1.json'),
"parseJSON" : true,
"path": "name"
},
"$main": {
"fetch" : "file://" + path.resolve(__dirname, '../dataset/1.json'),
"parseJSON" : true,
"path": "main",
}
};
add: key, value
- module: basics
Add a key/value pair into the input object.
{
"input": { },
"stylesheet": {
"add": ["tag", "span"]
},
"expected": {
"tag": "span"
}
}
{
"input": {
"content": "not empty"
},
"stylesheet": {
"add": ["tag", "span"]
},
"expected": {
"content": "not empty",
"tag": "span"
}
}
expect: object
- module: basics
Set default key/values for the input object: when a key is not present in the input object, it is set the value given in the argument object.
{
"input": {
"a": 3
},
"stylesheet": {
"expect": {
"a": 1,
"b": 2
}
},
"expected": {
"a": 3,
"b": 2
}
}
{
"stylesheet": {
"expect": {
"a": 1,
"b": 2
}
},
"expected": {
"a": 1,
"b": 2
}
}
inject:
- module: basics
Return a new Object with JBJ.inject.
render:
- module: basics
Return a new Object with JBJ.render.
compute:
- module: basics
Compute an expression with all variables of the input. Use the filtrex syntax.
Note : this
variable contains input
var stylesheet = {
"set" : {
"a" : 20,
"b" : 3,
"c" : 5,
"d" : 8
},
"$x" : {
"compute#1": "a / b",
"compute#2": "round(this)",
"cast": "number"
},
"$y" : {
"path": "b",
"cast": "number"
},
"$z" : {
"compute": "x + y",
}
};
// output : 10
debug: none
- module: basics
Print input with console.log
var stylesheet = {
"set": "value",
"debug": true
};
// output: value
foreach: stylesheet
- module: basics
Apply stylesheet on all elements of input
var stylesheet1 = {
"set": ["value", "value", "value"]
"foreach" : {
"upcase" : true
}
};
// output : ["VALUE", "VALUE", "VALUE"]
var stylesheet2 = {
"set": [
{ "b" : "x" },
{ "b" : "y" }
],
"foreach" : {
"get": "b",
"upcase" : true
}
};
// output : ["X", "Y"]
var stylesheet3 = {
"set": [
{ "b" : "x" },
{ "b" : "y" }
],
"foreach" : {
"$b" : {
"get": "b",
"upcase" : true
}
}
};
// output : [ { "b" : "X" }, { "b" : "Y" } ]
extend: object
- module: basics
- aliases : extendWith
Extend input with another object
var stylesheet = {
"set": {
"a" : 1
},
"extend" : {
"b" : 2
}
};
// output : { a: 1, b: 2}
select: path | path, path, ...
- module: basics
Peck element(s) in input with "CSS selector"
var stylesheet = {
"set" : {
"a" : {
"b" : [
{ "c" : "1" },
{ "c" : "2" }
]
}
},
"select" : ".a > .b .#c"
};
// output : [1, 2]
for syntax see JSONSelect and JSONSelect Expression Tester
Note:
select
always returns an array (an empty array when nothing was selected).
cast: (number|string|boolean) | (string|date), pattern
- module: basics
Convert input to specific type
var stylesheet1 = {
"set" : "1"
"cast": "number"
};
// output : 1
var stylesheet2 = {
"set" : 1
"cast": "string"
};
// output: "1"
for syntax see transtype
mask: pattern
- module: basics
Selecting specific parts of input, hiding the rest, return object
var stylesheet = {
"set" : {
"a" : 1,
"b" : 2,
"c" : 3
},
"mask": "a,c"
};
// output : { a: 1, c: 3}
For syntax see json-mask
omit: pattern
- module: basics
Unselecting specific parts of input, show the rest, return object
var stylesheet = {
"set" : {
"a" : 1,
"b" : 2,
"c" : 3
},
"omit": "a,c"
};
// output : { b: 2 }
For syntax see object.omit
required: none
- module: basics
If input is not set, return Error
trim: none
- module: basics
Trim input, return string
var stylesheet = {
"set" : " xxx ",
"trim": true
};
// output : "xxx"
assert: expression
- module: basics
If expression is true, then statements will be continued, otherwise it is stopped and it returns null
Note :
this
variable contains input
var stylesheet1 = {
"set" : {
"a" : 1
},
"$val#1" : {
"assert": "a == 1",
"set" : "if val"
}
};
// output : "if val"
var stylesheet2 = {
"set" : {
"a" : 0
},
"$val#1" : {
"assert": "a == 1",
"set" : "if val"
},
"$val#2" : {
"get" : "val",
"default": "else val",
}
};
// output : "else val"
capitalize:
- module: ejs
Capitalize the first letter of input
var stylesheet = {
"set" : "xyz",
"capitalize": true
};
// output : "Xyz"
downcase:
- module: ejs
Downcase input
var stylesheet = {
"set" : "XYZ",
"downcase": true
};
// output : "xyz"
upcase:
- module: ejs
Uppercase input
var stylesheet = {
"set" : "xyz",
"upcase": true
};
// output : "XYZ"
slug:
- module: ejs
Convert the input string to something valid in an URI. See https://tools.ietf.org/html/rfc3986
{
"slug spaces": {
"input": "with space",
"stylesheet": {
"slug": true
},
"expected": "with-space"
},
"slug lowercase": {
"input": "IN UPPERCASE",
"stylesheet": {
"slug": true
},
"expected": "in-uppercase"
},
"slug diacritics": {
"input": "En français",
"stylesheet": {
"slug": true
},
"expected": "en-francais"
},
"slug diacritics #2": {
"input": "Le Cinquième Élément",
"stylesheet": {
"slug": true
},
"expected": "le-cinquieme-element"
},
"slug unicode": {
"input": "i ♥ unicode",
"stylesheet": {
"slug": true
},
"expected": "i-unicode"
}
}
first:
- module: ejs
Get the first element of input
var stylesheet = {
"set" : ["a", "b", "c"],
"first": true
};
// output : "a"
last:
- module: ejs
Get the last element of input
var stylesheet = {
"set" : ["a", "b", "c"],
"last": true
};
// output : "c"
sort:
- module: ejs
Sort input object or array.
var stylesheet = {
"set": ["b", "c", "a"],
"sort": true
};
// output : ["a", "b", "c"]
sortBy: prop | prop, prop, ...
- module: ejs
- aliases : sort_by
Sort input object the given prop
ascending.
var stylesheet = {
"set": [
{ "name": "zert" },
{ "name": "abcd" }
],
"sortBy": "name"
};
// output : [{ "name": "abcd" }, { "name": "zert" }]
size:
- module: ejs
- aliases : length
Get the size or the length of input
var stylesheet1 = {
"set" : "12345",
"size": true
};
var stylesheet2 = {
"set" : [1,2,3,4,5],
"size": true
};
// output : 5
max:
- module: ejs
Add input and value
var stylesheet1 = {
"set" : [2, 4, 1, 7, 9, 3],
"max" : true
};
// output : 9
var stylesheet2 = {
"set" : {a: 9, b: 4, c: 3, d: 5},
"max" : true
};
// output : 9
min:
- module: ejs
Subtract value from input
var stylesheet1 = {
"set" : [2, 4, 1, 7, 9, 3],
"min" : true
};
// output : 1
var stylesheet2 = {
"set" : {a: 9, b: 4, c: 3, d: 5},
"min" : true
};
// output : 3
plus: value | value, value, ...
- module: ejs
Add input and value
var stylesheet = {
"set" : 4,
"plus": 3
};
// output : 7
var stylesheet = {
"set" : 4,
"plus": [1,2,3]
};
// output : [5,6,7]
minus: value | value, value, ...
- module: ejs
Subtract value from input
var stylesheet = {
"set" : 4,
"minus": 3
};
// output : 1
var stylesheet = {
"set" : 4,
"minus": [1,2,3]
};
// output : [3,2,1]
times: value | value, value, ...
- module: ejs
Multiply input by value"
var stylesheet = {
"set" : 5,
"times": 5
};
// output : 25
var stylesheet = {
"set" : 4,
"times": [1,2,3]
};
// output : [4,8,12]
dividedBy: value | value, value, ...
- module: ejs
- aliases : divided_by
Divide input by value"
var stylesheet = {
"set" : 10,
"dividedBy": 2
};
// output : 5
var stylesheet = {
"set" : 4,
"times": [1,2]
};
// output : [4,2]
join: string = ', '
- module: ejs
- aliases : glue
Join input with the given string.
var stylesheet = {
"set" : ["a","b","c"],
"join": " | "
};
// output : "a | b | c"
shift: n | n, n, ...
- module: ejs
Shift input to the left by n
var stylesheet = {
"set" : "The world",
"shift": 4
};
// output : "world"
var stylesheet = {
"set" : [1,2,3,4,5],
"shift": 2
};
// output : [3,4,5]
var stylesheet = {
"set" : [1,2,3,4,5],
"shift": [2,3]
};
// output : [[3,4,5],[4,5]]
truncate: length | length, length, ...
- module: ejs
Truncate input to length.
var stylesheet = {
"set" : "hello world",
"truncate": 5
};
// output : "hello"
truncateWords: n | n, n, ...
- module: ejs
- aliases : truncate_words
Truncate input to n words (separator: space).
var stylesheet = {
"set" : "This is JBJ!",
"truncateWords": 2
}
// output "This is"
var stylesheet = {
"set" : "This is JBJ!",
"truncateWords": [1,2]
}
// output ["This","This is"]
replace: pattern, substitution | pattern
- module: ejs
Replace pattern (as a regular expression) with substitution in input.
var stylesheet = {
"set" : "XoXoXoX",
"replace": ["o", "."]
};
// output : X.X.X.X
var stylesheet = {
"set" : "XoXoXoX",
"replace": "o"
};
// output : XXXX
Tip: to escape any character, use
\\
instead of just\
. Example: use"replace": "\\(trash\\)"
removes(trash)
from input, whereas"replace": "(trash)"
removes onlytrash
.
prepend: something | something, something, ...
- module: ejs
Prepend something to input
var stylesheet = {
"set" : "world"
"prepend": "hello"
};
// output : "hello world"
var stylesheet = {
"set" : "h"
"prepend": ["a","e","i","o","u"]
};
// output : ["ah","eh","ih","oh","uh"]
append: something | something, something, ...
- module: ejs
Append something to input
var stylesheet = {
"set" : "cool",
"append": "!"
};
// output : "cool!"
var stylesheet = {
"set" : "cool",
"append": ["!","?","."]
};
// output : ["cool!","cool?","cool."]
reverse:
- module: ejs
Reverse items order of input
var stylesheet = {
"set" : [1,2,3]
};
// output : [3,2,1]
flatten:
- module: ejs
Flatten an array.
var stylesheet = {
"set" : [ ['a', 'b'], ['c', 'd'], 'e'],
"flatten" : true
};
// output : ["a","b","c","d","e"]
deduplicate:
- module: ejs
- aliases : dedupe , unique
Deduplicate values in an array.
var stylesheet = {
"set" : [ 1, 2, 3, 1, 2],
"deduplicate" : true
};
// output : [1,2,3]
remove:
- module: ejs
- alias : del
Remove one value in an array.
var stylesheet = {
"set" : [ 1, 2, 3],
"remove" : 2
};
// output : [1,3]
var stylesheet = {
"set" : [ "a", "", "b"],
"remove" : ""
};
// output : ["a","b"]
var stylesheet = {
"set" : [ "a", "b", "c"],
"remove" : "b"
};
// output : ["a","c"]
sum:
- module: ejs
- alias : total
Return the sum of all the value of an array.
var stylesheet = {
"set" : [ 1, 2, 3],
"sum" : true
};
// output : 6
FAQ
How to chain the same action
just add #
var stylesheet = {
"default": "123456789",
"truncate#1": 8,
"truncate#2": 4,
"truncate#3": 2
};
How to use input as variable in an expression
just use this
var stylesheet = {
"$e" : {
"compute#1": "a / b",
"compute#2": "round(this)",
"cast": "number"
}
}
How to find more examples
see unit tests : https://github.com/castorjs/node-jbj/tree/master/test
Also
- http://goessner.net/articles/jsont/
- http://stedolan.github.io/jq/
- http://danski.github.io/spahql/
- https://github.com/MaxMotovilov/adstream-js-frameworks/wiki/Jxl-usage
- http://www.jsoniq.org/
License
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago