A new way to transform JSON object with a JSON stylesheet. It's like XSL/XML but only with JSON.
With npm do:
$ npm install jbj
Use mocha to run the tests.
$ npm install
$ npm test
Render input
with stylesheet
.
var JBJ = require('jbj'),
JBJ.render({ "truncate" : 3 }, "1234", function(err, out) {
console.log(out);
});
// Output : 123
Render input
with stylesheet
.
var JBJ = require('jbj'),
out = JBJ.renderSync({ "truncate" : 3 }, "1234");
console.log(out);
// Output : 123
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);
});
To add a filter simply add a method to the .filters object:
jbj.filters.concatx = function(obj, args) {
return String(obj) + String(args) + 'X;
};
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 = {
"$?" : "https://raw.githubusercontent.com/castorjs/node-jbj/master/package.json",
"$name" : {
"upcase": true
},
"$main": {
"upcase": true
}
};
var stylesheet_2 = {
"$name" : {
"$?" : "file://" + path.resolve(__dirname, '../dataset/1.json'),
"parseJSON" : true,
"path": "name"
},
"$main": {
"$?" : "file://" + path.resolve(__dirname, '../dataset/1.json'),
"parseJSON" : true,
"path": "main",
}
};
Variable can be set using $ plus a dot notation path.
var stylesheet = {
"$x" : {
"get": "a.b.c",
},
"$y.y1.y2" : {
"get": "a.d"
}
}
Set value and ignore input
var stylesheet1 = {
"set": "value"
};
var stylesheet2 = {
"set": ["value", "value", "value"]
};
var stylesheet3 = {
"set": {
"a": 1,
"b": 2
}
};
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]
Fix value if input is not set
var stylesheet = {
var stylesheet = {
"default": "value"
};
};
Print input with console.log
var stylesheet = {
"set": "value",
"debug": true
};
// output: value
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" } ]
aliases : extendWith
Extend input with another object
var stylesheet = {
"set": {
"a" : 1
},
"extend" : {
"b" : 2
}
};
// output : { a: 1, b: 2}
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
Replace a value by the matching value in the object.
{
"set": "one",
"mapping": {
"one": 1
}
}
// output: 1
{
"set": "FR",
"mapping": {
"US": "United States of America",
"FR": "France"
}
}
// output: "France"
Can also replace the values of an array with the matching values in the object.
{
"set": [1, 2],
"mapping": ["a","b","c"]
}
// output: ["b","c"]
{
"set": ["a", "b"],
"mapping": {
"a": "Aha!",
"b": "Baby"
}
}
// output: ["Aha!","Baby"]
alias: combine
Replace the content of the input
variable according to the content of the table
variable.
var input = {
"arg": { "a": "Aha!", "b": "Baby"},
"input": "a"
};
var stylesheet = {
"mappingVar": ["input", "arg"]
};
var output = JBJ.renderSync(stylesheet, input);
// output "Aha!";
Convert an array, which items have key
and value
properties, to an associative array (or object), which key properties are key
values and values are value
values.
Note: when the parameter is not a two items array, its default value is
["_id","value"]
.
Ex:
var stylesheet = {
"set": [
{
"_id": "2007",
"value": 538
}, {
"_id": "2008",
"value": 577
}, {
"_id": "2009",
"value": 611
}],
"array2object": true
};
// output = { "2007": 538, "2008": 577, "2009": 611 }
var stylesheet = {
"set": [
{
"key": "2007",
"val": 538
}, {
"key": "2008",
"val": 577
}, {
"key": "2009",
"val": 611
}],
"array2object": ["key","val"]
};
// output = { "2007": 538, "2008": 577, "2009": 611 }
Join two arrays (which elements have an _id
and a value
keys).
var stylesheet = {
"set": {
"array1": [{"_id": "1", "value": 1}, {"_id": "2", "value": 2}],
"array2": [{"_id": "1", "value": 10}, {"_id": "2", "value": 20}]
},
"zip": [ "array1", "array2" ]
};
var output = JBJ.renderSync(stylesheet);
// output: [ { _id: '1', array1: 1, array2: 10 },
// { _id: '2', array1: 2, array2: 20 } ]
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
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
Pack input to CSV, return string
var stylesheet = {
"set" : ["x","y","z"],
"csv" : ","
};
// output : "x,y,z"\r\n
aliases : fromCSV, uncsv
Parse input as CSV string, return array
var stylesheet = {
"set" : "x,y,z",
"parseCSV": ",",
};
// output : ["x","y","z"]
alias : toJSON
Pack input to JSON, return string
var stylesheet = {
"set" : ["x","y","z"],
"json": true
};
// output : "[\"x\",\"y\",\"z\"]"
aliases : fromJSON, unjson
Parse input as JSON string, return object
var stylesheet = {
"set" : "[\"x\",\"y\",\"z\"]",
"parseJSON": true
};
// output : ["x","y","z"]
Pack input to XML, return string
options are detailed in the xml-mapping documentation
var stylesheet = {
"set": {
"root" : {
"item" : [
{ "index" : "1", "$t" : "A"},
{ "index" : "2", "$t" : "B"},
{ "index" : "3", "$t" : "C"}
]
}
},
"xml" : {
"indent": false
}
};
// output : <root><item index="1">A</item><item index="2">B</item><item index="3">C</item></root>
aliases : fromXML, unxml
Parse input as XML string, return object
options are detailed in the xml-mapping documentation
var stylesheet = {
"set": "<root><item xml:id=\"1\">A</item><item xml:id=\"2\">B</item><item xml:id=\"3\">C</item></root>",
"parseXML" : {
"specialChar": "#",
"longTag" : true
}
};
// output : { root : { item : [ { xml#id: 1, #text: A }, { xml#id: 2, #text: B }, { xml#id: 3, #text: C } ] } }
Get the first non-undefined value
var stylesheet = {
"set" : [null, undefined, null, "a", "b"],
"coalesce": true
};
// output : "a"
If input is not set, return Error
Trim input, return string
var stylesheet = {
"set" : " xxx ",
"trim: true
};
// output : "xxx"
Build a string with mustache template and input
var stylesheet = {
"set" : {
"a" : {
"b" : "hello"
},
"c" : "world"
},
"template": "I say {{a.b}} to the {{c}}"
};
// output : I say hello to the world
Compute an expression with all variables of the input.
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
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 the first letter of input
var stylesheet = {
"set" : "xyz",
"capitalize": true
};
// output : "Xyz"
Downcase input
var stylesheet = {
"set" : "XYZ",
"downcase": true
};
// output : "xyz"
Uppercase input
var stylesheet = {
"set" : "xyz",
"upcase": true
};
// output : "XYZ"
aliases : substr
var stylesheet = {
"set" : "20150310",
"substring" : [4,2]
};
// output : "03"
Get the first element of input
var stylesheet = {
"set" : ["a", "b", "c"],
"first": true
};
// output : "a"
Get the last element of input
var stylesheet = {
"set" : ["a", "b", "c"],
"last": true
};
// output : "c"
Sort input object or array.
var stylesheet = {
"set": ["b", "c", "a"],
"sort": true
};
// output : ["a", "b", "c"]
aliases : sort_by
Sort input object the given prop
ascending.
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
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
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
Add input and value
var stylesheet = {
"set" : 4,
"plus": 3
};
// output : 7
var stylesheet = {
"set" : 4,
"plus": [1,2,3]
};
// output : [5,6,7]
Subtract value from input
var stylesheet = {
"set" : 4,
"minus": 3
};
// output : 1
var stylesheet = {
"set" : 4,
"minus": [1,2,3]
};
// output : [3,2,1]
Multiply input by value"
var stylesheet = {
"set" : 5,
"times": 5
};
// output : 25
var stylesheet = {
"set" : 4,
"times": [1,2,3]
};
// output : [4,8,12]
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]
aliases : glue
Join input with the given string.
var stylesheet = {
"set" : ["a","b","c"],
"join": " | "
};
// output : "a | b | c"
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 input to length.
var stylesheet = {
"set" : "hello world",
"truncate": 5
};
// output : "hello"
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 with substitution in input.
var stylesheet = {
"set" : "XoXoXoX",
"replace": ["o", "."]
};
// output : X.X.X.X
var stylesheet = {
"set" : "XoXoXoX",
"replace": "o"
};
// output : XXXX
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 to input
var stylesheet = {
"set" : "cool",
"append": "!"
};
// output : "cool!"
var stylesheet = {
"set" : "cool",
"append": ["!","?","."]
};
// output : ["cool!","cool?","cool."]
Reverse items order of input
var stylesheet = {
"set" : [1,2,3]
};
// output : [3,2,1]
Flatten an array.
var stylesheet = {
"set" : [ ['a', 'b'], ['c', 'd'], 'e'],
"flatten" : true
};
// output : ["a","b","c","d","e"]
aliases : dedupe , unique
Deduplicate values in an array.
var stylesheet = {
"set" : [ 1, 2, 3, 1, 2],
"deduplicate" : true
};
// output : [1,2,3]
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"]
aliases : getProperty, getproperty, getIndex
Get a property of an object, or an item of an array.
var stylesheet = {
"set" : [ "a", "b", "c" ],
"getindex": "2"
};
// output : "c"
var stylesheet = {
"set" : { "a": 0, "b": 1, "c":2 },
"getproperty": "b"
};
// output : 1
aliases : getPropertyVar, getpropertyvar, getIndexVar
Get a property of an object, or an item of an array, like getindex, but using variables.
var stylesheet = {
"set": {
"i": 1,
"t": ["a","b","c"]
},
"getIndexVar": ["t", "i"]
};
// output : "b"
var stylesheet = {
"set": {
"i" : "b",
"o" : { "a": 0, "b": 1, "c":2 },
},
"getPropertyVar": ["o", "i"]
};
// output : 1
alias : total
Return the sum of all the value of an array.
var stylesheet = {
"set" : [ 1, 2, 3],
"sum" : true
};
// output : 6
just add #
var stylesheet = {
"default": "123456789",
"truncate#1": 8,
"truncate#2": 4,
"truncate#3": 2
};
just use this
var stylesheet = {
"$e" : {
"compute#1": "a / b",
"compute#2": "round(this)",
"cast": "number"
}
}
see unit tests : https://github.com/castorjs/node-jbj/tree/master/test