Java8 is required.
With a method defined as:
private Object evaluate(String jsonDocument, String javascriptFunction) {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
String script = "var fun = function(document) {\n" +
" return JSON.parse(document)." + javascriptFunction + ";\n" +
"};";
System.out.println(script); // debug
engine.eval(script);
Invocable invocable = (Invocable) engine;
return invocable.invokeFunction("fun", jsonDocument);
} catch (ScriptException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
It is simple to access and manipulate nested properties with a Javascript expression:
String document = new Scanner(this.getClass().getClassLoader().getResourceAsStream("sample.json"), "UTF-8").useDelimiter("\\A").next();
Object result = evaluate(document, "menu.id");
// String[file]
// Javascript functions are available
result = evaluate(document, "menu.popup.menuitem.map(function (item) {return item.value;})");
// ScriptObjectMirror(Array)[New, Open, Close]
// Nashorn Function Literals
result = evaluate(document, "menu.popup.menuitem.map(function (item) item.value)");
// ScriptObjectMirror(Array)[New, Open, Close]