XML Template

Each template is a valid XML with a format described below.

Tags and Attributes

There is one special tag cj:block and several special tag attributes:

  • cj:with
  • cj:if
  • cj:unless
  • cj:switch
  • cj:case
  • cj:each

in the given precedence order.

All special tags and attributes are not included in the template processing result.

Syntax Definitions

  • number is a string which contains only digits
  • variable is a string which contains only digits, letters, underscore character (_) and does not start with a digit
  • reference = "variable" | "reference.fnumber"
  • value = "*" | "null" | "true" | "false" | "number"
  • format = "Dnumber" | "Fnumber" | "Bnumber" | "Vnumber"

Variables and References

Each XML tag subtree has an associated set of variables. There is one global variable object which corresponds to the root data object used for template processing. Local variables can be defined within tags via special attributes cj:with and cj:eachA local variable is defined in a scope of its tag and can hide a variable with the same name from outer scope.

Each variable corresponds to some data instance which is derived from a reference string. A reference string should always start from an already defined variable in the current score. It is processed from left to right where a number in ".fnumber" corresponds to a field identifier.

Placeholders

Braces { and } are used to define placeholders in each template lineFor each opening { there must be a closing one } and vice a versa. The braces are escaped by double braces {{ and }} correspondingly. A placeholder is defined by each opening brace as a substring from the brace to the closest closing brace on the right. The placeholder syntax is "{reference}" | "{reference:format}" where the first character of format stands for:

  • D: decimal with the given minimal number of characters, if the number starts with zero (0) prepend the output with zeros instead of spaces
  • F: float with the given precision
  • B: boolean, B0 stands for lowercase and B1 stands for uppercase
  • V: string view with the given identifier

Each placeholder has to be replaced with the reference data value serialized according to default or specified format using the current locale and timezone.

cj:block

It is the only special tag which means the current tag subtree still has to be processed but the tag itself is not added to the result. For example,

<root>
  <cj:block someattr="somevalue">
    <a>This is an inner tag.</a>
    <cj:block>This is an inner text.</cj:block>
  </cj:block>
</root>
will result in
<root>
  <a>This is an inner tag.</a>
  This is an inner text.
</root>

cj:with

Defines a new local variable in a scope of its tag. The syntax is cj:with="variable = reference"For example

<a cj:with="my_var = object.f47.f77">
  <b>The value is {my_var.f4477}</b>
</a>

cj:if and cj:unless

If a tag has cj:if (similarly cj:unless) attribute its subtree is processed only if the corresponding data reference is not null. The syntax is cj:if="reference"

<a cj:if="object.f47.f77">
  The parent tag will be added to the result only if object.f47.f77 is not null.
</a>

cj:switch and cj:case

The syntax is cj:switch="reference" and cj:switch="value"If a tag has cj:switch attribute at most one of its child tags will be processed. Consider all child tags with cj:switch attribute in the given order. The first tag with reference data matching the value will be processed (possibly none).

A reference data matches a value if one of the following holds

  • value = "*"
  • value = "null" and the reference data is null
  • value = "true" and the reference data = true
  • value = "false" and the reference data = false
  • value is number equal to the reference data

For example

<cj:block cj:switch="object.f47">
  <a cj:case="null">There is no value.</a>
  <b cj:case="0">The value is zero.</b>
  <c cj:case="*">The value is {object.f47}.</c>
</cj:block>

cj:each

Instructs to iterate over a collection using a local variable. The syntax is cj:each="variable : reference"The reference should point to a collection. For example

<a cj:each="item : object.f44">
  <b>The value is {item.f777}</b>
</a>