Skip to content
Like XSL/XML but for JSON.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
dataset
lib
test
.gitignore
.npmignore
README.md
index.js
package.json

README.md

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):

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 and ejs modules are distributed with the jbj package, and used by default: you can use their actions without any further declaration. However, parse, template, and array, which were parts of the pre-3.0 versions of JBJ are now separate packages (simply add jbj- 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 only trash.

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

License

MIT

You can’t perform that action at this time.