Dmitry Filatov
Indexes by means of XSLT 17 March 2006 |
|
Task: | Create a universal template for making indexes of unsorted data. | ||
Wed like to guarantee future usefulness of the template, so lets complicate the task and suppose that:
— initial set has random structure;
— initial data is unsorted;
— number of columns is unknown;
— alphabetical blocks are arranged into columns evenly.
Initial data sample
|
Full sample |
What its going to look like
If the index has several columns there are two ways to arrange them:
A
B
C
|
E
F
H
|
J
L
M
|
R
T
W
|
A
| B
| C
| E
|
F
| H
| J
| L
|
M
| R
| T
| W
|
Processing random set of data
We need a universal technique, so the initial set of data must be processed regardless of its structure. To enable this we can render it for the index template as nodelist. Other properties include:
key-name — name of a key based on first letter (I am going to specify its purpose further on; at this point, its important that the number of nodes to which we assign a key value equals to the number of nodes implemented by nodelist);
count-columns — number of columns for arranging the data;
direction — way of filling the columns (0 — vertical, 1 — horizontal).
Here is a sample script activating the index template:
|
Template alpha-indexes.xsl has some features of particular interest that deserve closer attention. All inner templates must be capable of processing random nodes. An appropriate XPath expression takes care of it:
|
See template alpha-indexes.xslt |
Generating alphabetical blocks
What does the trick is that Rows filled horizontally
Id like to explain why I use the for-each outer loop instead of direct call on the row with specified predicate. The thing is that the initial data is unsorted, whereas we need to know the block position in a sorted set. So we first do the sorting, and then check the position. Columns filled vertically
However, its not that simple. If the task is to divide 12 blocks into 5 columns. The number of blocks in a complete column would be 3, and the whole set of blocks would fit into 4 columns which conflicts with the task. For this reason we need to generate additional columns when necessary. The script that arranges the blocks realizing this approach is rather lengthy, so its not included in this article. Moreover, the template for generating columns has to count how many blocks are to appear in each of the columns (to be able to pass that number to the next template responsible for generating blocks in the column). Number of blocks in a column filled vertically
Creating block contents
|
Also see Grouping using the Muenchian method |