Location Paths are the expressions similar to XPath, which are used in DocFlex templates to specify the search of the elements or the attributes.
Although eventually they are string, during designing the templates in the DocFlex Template Designer, the Location Paths are normally not needed to enter directly. Instead, they are constructed using special dialogs or can be selected in the Location Path Chooser, like the one shown on this screenshot:
Each Location Path is interpreted relatively to a certain selected element (context node), which normally is the generator's context element. As the result of such an interpretation, a set of elements (Element Location Paths) or attributes (Attribute Location Paths) is generated.
Step1 / Step2 / ... / StepN
Step1, ..., StepN-1
StepN
Each Location Path is interpreted by the successive interpretation of the Location Steps defined in it. During the interpretation of each step, an intermediate set of the DSM's nodes is collected. That set is called the step's result set. The result set of the last step becomes the result of the whole Location Path interpretation. When a certain step produces an empty set, so will be the result of the whole Location Path.
Each Location Step is always interpreted relatively to a certain its own context node (i.e. an element) according to the rules:
axis :: ETs [filter]axis
childaxis:: prefix is specified in the location step).selfchild-or-selfdescendantdescendant-or-selfattribute^
The attribute is the name of a certain context element's attribute
(whose type should be either IDREF or IDREFS).
Such a specification is interpreted in the following way.
When the context element contains an attribute with 'attribute' name,
all values of that attribute are interpreted as the identifiers of elements that may be contained
in the DSM.
Each identifier is used to find a corresponding element, and, if found,
that element is added to the step's result set.
Example:
elementReference^::ClassDoc
{ expr }
The elements included in that axis are produced by the FlexQuery expression
specified between the curly brackets. The expression should return the enumeration
of new elements, which it may produce from the step's context node (the element)
passed to the expression as the
generator context element
(accessible via the contextElement variable).
For example, the step:
child::Person
will do the same as the step:
{ findChildren("Person") }::Person
The real power of the formula-axis is that you can program within the embedded expression
any method of finding elements (including finding them using element maps).
That profoundly transforms capabilities of the entire search possible to organize using
Location Paths!
Note: The expression specified in formula-axis should always return the
Enumeration type. Otherwise, the generator will raise an error.
The returned enumeration should contain objects of GOMElement
or DSMElement types (objects of other types will be ignored).
The null value returned by the expression will be interpreted as
an empty enumeration.
ETs(ET1 | ET1 | ... | ETn),
where each ETn is an Element Type name.
*), which will include
all elements regardless of their type
filter
When specified, this subquery is executed for each element to be included in the step's result set.
An element is included in the result set only when the subquery returns true.
The tested element is accessible within the subquery as the
generator context element
(via the contextElement variable).
The previous context element is overshadowed (it is restored again after the Location Path
processing is finished).
Each Attribute Location Step has the following structure:
@attribute
where attribute is the name of the searched attribute.
The Attribute Location Paths are normally used to collect values of
the same attribute by a number of elements at once.
lpath1 | lpath2 | ... | lpathN
Such an expression is called Compound Location Path and interpreted by
the successive interpretation of the Location Paths contained in it.
The result is a union of elements or attributes produced by each constituent
Location Path.
Matching Element Types → Element Location Path
Matching Element Types
*
Element Location Path
As in the case of template components, for each rule an additional enabling condition can be defined in the form of the boolean FlexQuery-expression.
A set of Element Location Rules is interpreted relatively to a certain context element (which is normally the same as the context element received by the section).
Each Element Location Rule is interpreted in the following way. At first, the rule is tested for compatibility with the context element's type and, in the case it has an enabling condition, if the condition is satisfied (the context element is accessible within the enabling condition expression via the generator's context element variable). If the both tests passed the rule's Element Location Path is interpreted relatively to the context element and a set of new elements produced. These elements are added to the total resulting set of all rules.
Example:
Let's consider the data source that provides the basic information about a Java-project. It can be described with the following DTD:
<!ELEMENT field> <!ELEMENT method> <!ELEMENT class (field*,method*,class*)> <!ELEMENT package (class*,package*)>Here are the sample Element Location Rules defined for this data source:
- Collect all classes (including the inner classes) contained both in the context element and in all its descendants:
* → descendant::class- If the context element is a package collect all top-level classes contained both in it and in all its subpackages:
package → child-or-self::package/child::class
It can be seen from the description above that the only way to specify searching of elements
at the arbitrary depth from the context node is using one of the
descendant-axes
in the Element Location Path of a rule,
and in this way, the search will involve all the context node's subtree at the
Element Location Step
where a descendant-axis is used.
However, in some situations, it may require to limit the search to only some branches of a subtree.
Constructing the Element Location Paths
using descendant-axes not always allows to achieve the necessary effect.
Even more difficulties arise when searching elements at the arbitrary depth involves using
link-axes.
The problem was solved in DocFlex by introduction the Recursive Location Rules.
Recursive Location Rules are the normal
Element Location Rules that, in addition,
have a special recursive flag
.
This affects their interpretation.
The set of the Element Location Rules which includes the recursive rules is interpreted according to the following repeatable steps:
Step 1: All the rules (recursive and not) are interpreted relatively to the context element received by the Element Iterator as described in the previous section. As result, some intermediate set of new elements is produced. All these elements are added to the generated EIS.
Step N+1: For the new element from the intermediate set generated at the Step N, the interpretations of the rules are repeated with each element selected as the rules' context one. But now, only those rules are used that have the recursive flag. All new elements produced by those interpretations are accumulated into a new intermediate set. They are also added to the generated EIS.
The iterations of the steps are continued until on some step no new elements produced.
Note: DocFlex distinguishes elements by their ID. Therefore, only those elements are considered as the new ones whose IDs have not yet occured on the previous iterations. Such an approach helps to prevent the infinite looping when the processed elements contains cyclic references, however, it requires each element to have the unique ID.
Example:
Let's consider a little more complicated version of the previous example. Now, the data source providing the information about a Java-project allows to know a parent of each class (if any it has) and the interfaces the class directly implements.The new DTD will be the following:
<!ELEMENT field> <!ELEMENT method> <!ELEMENT class (field*,method*,class*,interface*)> <!ELEMENT interface (field*,method*)> <!ELEMENT package (class*,interface*,package*)> <!ATTLIST class extends IDREF> <!ATTLIST interface extends IDREFS> <!ATTLIST class implements IDREFS>Let now our task is to collect all interfaces directly or indirectly implemented by a given class (this will include the interfaces directly implemented either by the class itself or by one of its ancestor classes and the interfaces that are the ancestors of those implemented directly). This can be done using the following set of Recursive Location Rules:
class → extends^::classclass → implements^::interface
interface → extends^::interface
![]()
The rules should be interpreted with the interested class as the initial context element. The result set should be filtered for the elements of
interfacetype.
There are four methods to specify the Element Iteration Scope (EIS) generation in the Element Iterator:
![]()
This is a simplified method, which allows to quickly and naturally define the Element Location Rule in the most cases. It requires specifying only four settings:
- Target Element Type
Defines one or many element types:TargetETswhich the elements of the generated EIS should conform to.- Include Descendants
Specifies if the search should include all descendants of the context element.- Include Self
Specifies if the context element itself can be included into the EIS (in the case its type is appropriate)- Filter Expression
Defines a filter for the EIS.Assigning of those settings will result in building automatically one of the following Element Location Rules:
* → child::TargetETs [filter]
* → descendant::TargetETs [filter]
* → child-or-self::TargetETs [filter]
* → descendant-or-self::TargetET [filter]
![]()
This is the most comprehensive method of defining Element Location Rules. It gives access to all features implemented in DocFlex. The generation of the EIS is specified with the following settings:
- Location Rules
The list of the Element Location Rules specifying how the EIS is generatedDefining a single Location Rule:
![]()
Defining a Location Step:
![]()
- Target Element Type
Defines one or many element types that the final EIS is filtered for to contain only elements of those types- Filter Expression
Specifies an additional filter for EIS
![]()
An alternative method of the EIS generation not based on Element Location Rules. The EIS is produced as the sequence of the connected elements, according to the following settings:
- Expression for First Element
The FlexQuery-expression calculating the first element for the EIS. The calculation normally should be based on the context element received by the section and may involve other generator variables.- Expression for Subsequent Element
All other EIS elements (except the first one) are calculated by this FlexQuery-expression. At each step, if the previous element was notnullit is made the context element. Then, the expression is processed and the next element is produced.- Target Element Type
Specifies the type of the elements that are included into the result EIS. In effect, this setting defines a filter that is applied to the EIS, once the initial set has been produced.- Filter Expression
Allows to define an additional filter for the EIS.
![]()
A yet another alternative method of EIS generation. It allows to organize iterations by an arbitrary set of elements provided by the specified FlexQuery-expression.
The following settings should be assigned in the Element Iterator properties:
- Target Element Type
Specifies the Element Type, to which the elements included in the result EIS should conform. The initial set of elements is filtered according to this condition.
- Expression for Element Enumeration
The FlexQuery-expression which should return an Enumeration of the elements for iteration.
The expression may employ various capabilities provided by FlexQuery functions (such as
findElementsByLPath(),findElementsByLRules(),findElementsByKey()).It is also possibility to generate a set of iterated elements by an external custom-witten Java class called using the
callForName()function.- Filter Expression
Allows to define an additional filter for the result EIS.
There are following options to specify sorting of the Element Iteration Scope (EIS):
No sorting. The EIS is remained in the original order (i.e. the one that is naturally formed when the elements are being inserted in the EIS).
Reverses the original order. This option may be particularly useful when the EIS is generated by Sequence method.
![]()
The elements of the EIS are sorted by the value of the specified attribute (according to its data type).
Additional settings:
- ordering: ascending/descending
- case sensitive (for character values only)
![]()
The elements of the EIS are sorted by their names (i.e. the names of their Element Types) in lexicographical order. This option makes sense when the EIS contains many elements of the different types.
Additional settings:
- ordering: ascending/descending
- case sensitive (for character values only)
![]()
The elements of the EIS are sorted by their values (regarding data types)
Additional settings:
- ordering: ascending/descending
- case sensitive (for character values only)
![]()
This is the most common method of sorting the EIS. It includes all previous methods and allows much more, though it might seem a little complicated. In this case, the elements of the EIS are sorted by an arbitrary compound key generated for each element.
Each compound key consists of a certain sequence of the subkeys:
subkey1; subkey2; ...; subkeyNthat is generated for each element before the sorting. The compound keys are compared by comparing consecutively their constituent subkeys in the order in which the subkeys follow.
Each subkey has its own method of calculation. This method also determines the subkey's data type, according to which the particular subkeys are compared.
The subkey calculation method can be specified as one of the following:
- by Location Path
The value of the subkey is assigned from the value of an element or attribute retrieved by the specified Location Path. The Location Path is interpreted relatively to the EIS element for which the whole key is generated. The Location Path also determines the subkey's data type.- by Formula
The value of the subkey is calculated by the specified FlexQuery-expression, which also determines the subkey's data type. The expression should derive the subkey value from the EIS element for which the whole key is generated. For doing so, the element is temporarily made the generator's context element and in this way can be accessed from within the expression.In addition to the calculation method, the comparison of the subkeys may be adjusted with following settings:
- subkey ordering: ascending/descending
- case sensitivity (for character subkeys only)