This node describes one
<Break>
.
<Break ... > <BreakHeader> <Output> ... </Output> </BreakHeader> <BreakFooter> <Output> ... </Output> </BreakFooter> <BreakFields> <BreakField /> ... </BreakFields> </Break>
The order in which Break
nodes are listed
matters for two reasons.
The primary reason is that break fields are hierarchical. The break fields listed earlier are higher in the hierarchy. If a break field earlier in the list triggers, all subsequent break fields also trigger implicitly.
The second reason is a consequence of the previous one: emitting the BreakHeaders occur in the order of the list. For logical reasons, BreakFooters are in reverse order.
The name of the break. It must be
unique in the list of breaks for
the parent <Report>
node.
<Break name="break1" />
After a break boundary, the header starts on a new page. Accepted in two variants:
<Break headernewpage="yes" /> <Break newpage="yes" />
The newpage="yes"
variant is
parsed but ignored in RLIB.
Suppress break header and footer in case
any of the break fields' values are either
NULL
or an empty string,
if the break field is of the string type.
<Break suppressblank="yes" />
The break header is printed before the new data row if it causes a break, i.e. the values in the set of break fields changed from one row to the next. It contains an Output node child node.
<BreakHeader> <Output> ... </Output> </BreakHeader>
The break header is printed after the previous data row if it causes a break, i.e. the values in the set of break fields changed from one row to the next. Also before the first row in the data set. It contains an Output node child node.
<BreakHeader> <Output> ... </Output> </BreakHeader>
The break fields node contains one or more BreakField children nodes.
<BreakFields> <BreakField ... /> ... </BreakFields>
The break field node only has one attribute and contains no child nodes.
<BreakField value="..."/>
The sole attribute in
<BreakField>
is
<value>
where the
expression watched for changes is declared.
See Expressions.
There must be at least one
<BreakField>
node
listed. When more than one break fields
are listed, then all of them are watched
for value changes. If any of them changes,
a break boundary occurs for the break.
This XML part below shows a complete example of nested breaks based on the real life example mentioned in Section 6.1.
<Report> <Breaks> <Break> <BreakHeader> <Output> <Line> <field value="query1.department" /> </Line> </Output> </BreakHeader> <BreakFooter> <Output> <Line> <literal>End of </literal> <field value="query1.department" /> </Line> </Output> </BreakFooter> <BreakFields> <BreakField value="query1.department" /> </BreakFields> </Break> <Break> <BreakHeader> <Output> <Line> <literal width="30" /> <field value="query1.paygrade" /> </Line> </Output> </BreakHeader> <BreakFooter> <Output> <Line> <literal width="30" /> <literal>End of </literal> <field value="query1.paygrade" /> </Line> </Output> </BreakFooter> <BreakFields> <BreakField value="query1.paygrade" /> </BreakFields> </Break> </Breaks> <Detail> <FieldHeaders> <Output> <Line> <literal width="60" /> <literal>Employee name</literal> </Line> </Output> </FieldHeaders> <FieldDetails> <Output> <Line> <literal width="60" /> <field value="query1.employee" /> </Line> </Output> </FieldDetails> <Detail> </Report>
Assuming that Size unit attribute is set to
points
, the indentation would be
30 and 60 points for certain elements (see the empty
<literal>
s) and the result
would look like this:
Before the first row on every page, the contents
of <FieldHeaders>
is
printed.
Before the first row, the contents of
<BreakHeader>
is printed for every break declared in
the <Report>
in
the order of their declaration.
The contents of
<FieldDetails>
is printed for the current row. Repeat until
a value change is observed between
adjacent rows for a break's expression.
In this case, the employees are printed
in one block that are in the current paygrade
category and working at the current department.
When a value change happened between
adjacent rows for a break's expression,
then this break and every break declared after
it triggers. For every triggering breaks,
their <BreakFooter>
is printed in the reverse order of their
declaration. This is done using the
previous row, so if any data
used from the row or derived from it (e.g. a
variable) and is to be displayed in the footer,
it will be valid for the break range that just
ended.
Before the new row, the contents of
<BreakHeader>
is printed for every break that just triggered.
For example, the department's name is not
printed if only the paygrade category changed
in the same department from the one row to
the next.
Repeat from step 3 until there are no more data rows.