|An alternative properties implementation|
The following discussion focusses on the relationship between
Flow Objects in the Flow Object tree, and properties. There
is no (or only passing) discussion of the relationship between
properties and traits, and by extension, between properties
and the Area tree. The discussion is illustrated with some
Property handling is complex and expensive. Varying numbers of
properties apply to individual Flow Objects
(FOs) in the FO
tree but any property may effectively be
assigned a value on any element of the tree. If that property
is inheritable, its defined value will then be available to
any children of the defining FO.
(XSL 1.0 Rec) 5.1.4 Inheritance
...The inheritable properties can be placed on any formatting
Even if the value is not inheritable, it may be accessed by
its children through the
inherit keyword or the
from-parent() core function, and potentially by
any of its descendents through the
from-nearest-specified-value() core function.
In addition to the assigned values of properties, almost every
property has an initial value which is used
when no value has been assigned.
The difficulty and expense of handling properties comes from
this univeral inheritance possibility. The list of properties
which are assigned values on any particular FO
element will not generally be large, but a current value is
required for each property which applies to the FO
The environment from which these values may be selected
includes, for each FO, for each applicable property,
the value assigned on this FO, the value which
applied to the parent of this FO, the nearest value
specified on an ancestor of this element, and the initial
value of the property.
One possibility is to push to the stack only a minimal set
of required elements. When a value is assigned, the
relevant form or forms of that value (specified, computed,
actual) are pushed onto the stack. As long as each
FO maintains a list of the properties which were
assigned from it, the value can be popped when the focus of
FO processing retreats back up the FO tree.
The complication is that, for elements which are not
automatically inherited, when an FO is encountered
which does not assign a value to the
property, the initial value must either be already at the
top of the stack or be pushed onto the stack.
As a first approach, the simplest procedure may be to push a
current value onto the stack for every element - initial
values for non-inherited properties and the parental value
otherwise. Then perform any processing of assigned values.
This simplifies program logic at what is hopefully a small
cost in memory and processing time. It may be tuned in a
Initial attempts at this implementation have used
LinkedLists as the stacks, on the assumption
- random access would not be required
pushing and popping of list elements requires nearly
constant (low) time
- no penalty for first addition to an empty list
- efficient access to both bottom and top of stack
However, it may be required to perform stack access
operations from an arbitrary place on the stack, in which
case it would probably be more efficient to use
An individual stack would contain values for a particular
property, and the context of the stack is the property class
as a whole. The property instances would be represented by
the individual values on the stack. If properties are to be
represented as instantiations of the class, the stack
entries would presumably be references to, or at least
referenced from, individual property objects. However, the
most important information about individual property
instances is the value assigned, and the relationship of
this property object to its ancestors and its descendents.
Other information would include the ownership of a property
instance by a particular FO, and, in the other
direction, the membership of the property in the set of
properties for which an FO has defined values.
In the presence of a stack, however, none of this required
information mandates the instantiation of properties. All
of the information mentioned so far can be effectively
represented by a stack position and a link to an
FO. If the property stack is maintained in
parallel with a stack of FOs, even that link is
implicit in the stack position.
Next: property classes overview.