8.14. Break #

8.14.1. Break attributes
8.14.2. Break subsections
8.14.3. A complete break example

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.

8.14.1. Break attributes #

8.14.1.1. Name #

The name of the break. It must be unique in the list of breaks for the parent <Report> node.

<Break name="break1" />

8.14.1.2. Header on new page #

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.

8.14.1.3. Suppress break header and footer for blank break fields #

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" />

8.14.2. Break subsections #

8.14.2.1. BreakHeader #

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>

8.14.2.2. BreakFooter #

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>

8.14.2.3. BreakFields #

The break fields node contains one or more BreakField children nodes.

<BreakFields>
    <BreakField ... />
    ...
</BreakFields>

8.14.2.3.1. BreakField #

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.

8.14.3. A complete break example #

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:

  1. Before the first row on every page, the contents of <FieldHeaders> is printed.

  2. Before the first row, the contents of <BreakHeader> is printed for every break declared in the <Report> in the order of their declaration.

  3. 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.

  4. 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.

  5. 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.

  6. Repeat from step 3 until there are no more data rows.