-
Notifications
You must be signed in to change notification settings - Fork 12
Jxl usage
Note that a JXL program — and, strictly speaking, any useful jtlc input in general — cannot be represented in JSON, because many of its nodes are objects with non-trivial constructors and prototypes.
JXL (JSON Transformation Language) — a specific template language implemented with jtlc (Javascript Template Language Compiler) for transforming and re-shaping JSON data. The language itself is also based on Javascript object notation but it is not JSON compliant: aside from the primitive types and object and array literals it also requires the use of functional tags which expand into non-anonymous — and invisible to the user of the library — Javascript objects.
The execution of a JXL template is best described in terms of the dataflow programming model: values are generated by some primitives, are operated upon by others resulting in new values and end up in sinks provided by a third kind of primitives. The behavior of most languages entities depends on whether they appear in a context of a singleton or an iteration:
In singleton context only a single value is processed. All primitives with parameters operate as functions insofar as they have no side effects.
In iterative context the values are produced in sequence by the innermost generator, undergo processing imposed by the primitives enclosing the generator and ultimately end up in a sink which limits the context. Array is the most typical sink for the iterative contexts though it is also possible to populate dictionaries (anonymous Javascript objects) iteratively or aggregate the results to a single value. The generators typically iterate over arrays passed in as template’s arguments, produced by executing a query over input data or built by other parts of the same template; it is also possible to iterate over keys in a dictionary.
As JXL was designed to build upon and extend the capabilities provided by dojox.json.query rather than as a replacement for the latter library, the examples in this section concentrate on use cases where dojox.json.query in itself is not sufficient to do the job. The author hopes that simpler patterns of JXL use can be easily derived from these examples by the reader.
Input | Template | Output |
|
|
|
Note that strings "author"
, "$[0].author"
and "[/author]"
are implicitly treated as expressions and a query, respectively, based on the execution context. At the same time, string “title” requires an explicit tag around it since it appears in an iterative context.
Using $[0]
in an expression within group body is an easy way to access the key fields as they are equal for the entire group anyway and the group is guaranteed to have at least one element. Simple expressions referencing the properties of the current input do not have "$."
in front of the name as it is implicitly assumed by expr()
.
Input | Template | Output |
|
|
|
For optimal performance, only one sorting on a composite key occurs here. The inner group()
operates on the current value (sequence of records with identical continent
key) of the outer one so it does not need the third argument.
Input | Template | Output |
|
|
|
In this example, using an object literal at JXL level to form the output records is not possible since it establishes an execution context of its own. Hiding it inside an expression solves the problem for simple cases. More complex aggregation patterns may require external accumulators implemented using an object or a closure:
Input | Template | Output |
|
|
|
Here, each()
is used to evaluate the object literal for each input array element (iteration over current input is assumed by each() when it is given only one argument).
Input | Template | Output |
|
|
|
Again, it is much easier to move object construction inside the inline expression than to deal with an object literal with a context of its own.
Input | Template | Output |
|
|
|
Note that the second expression does create an intermediate copy: it is necessary to pass multiple properties to the innermost iteration. This copy however is shallow and performance impact of it should be minimal.
The example above takes a simple record and transforms it into a data structure suitable to populate the names and values for controls in a form template.
At the moment, JXL lacks comprehensive support for SQL-like joins. Nevertheless some simple yet important cases — such as lookup by an unique key — can be implemented in a straightforward manner:
Input | Template | Output |
|
|
|
The association of the two tables relies on an intermediate dictionary with the key field of the join serving as the key in the dictionary. The same approach can be extended to compound keys by using replace()
to build their string representations.
see JXL Primitives