RobertNoble
asked on
Pseudo-Crosstab table in XSLT linked to WSS 3.0
Trying to manage and intuitively display a large amount of data, which breaks down like this:
2 main lists: Package List, Steps List
Each package had a Planned, Forecast and Actual (P/F/A) date associated with each Step, which is stored in a third list (Dates) and linked to the 2 other lists.
There are many steps in the Steps list, but only a dozen or so are of interest in the view I'm building, and are numbered sequentially in a specific column.
I've created a joined datasource in SPD2007, and managed to:
- for-each Step*, create a <th> entry in the first row
- for-each Package, create a new <tr> and a first cell which carries the package name and rowspan=3, then
- for each of the Planned, Forecast and Actual, continue/create a <tr>, then call a template (in the CODE section below) to fill in the data, by matching the package at the beginning of the row, and the column
The questions are these:
- Is there anything to be gained by replacing this structure with <apply-templates> rather than with <call-templates> and <for-each>
- Is it possible to lookup 'vertically' or pass a param somehow (or a sequence thereof) to obtain the steps (IDs) list for filtering the dates?
> Currently, my template relies on each date being created in order (within the Dates table), for correct display, and also doesn't account for missing values (i.e. a date for step 5 being entered without having a date for step 4) so mis-alignments w.r.t the column headers occur.
> I've tried using a nested for-each (selecting the relevant steps then the relevant dates) but the resulting processing causes my SPD to eat up 100's of MBs and slow to a halt.
2 main lists: Package List, Steps List
Each package had a Planned, Forecast and Actual (P/F/A) date associated with each Step, which is stored in a third list (Dates) and linked to the 2 other lists.
There are many steps in the Steps list, but only a dozen or so are of interest in the view I'm building, and are numbered sequentially in a specific column.
I've created a joined datasource in SPD2007, and managed to:
- for-each Step*, create a <th> entry in the first row
- for-each Package, create a new <tr> and a first cell which carries the package name and rowspan=3, then
- for each of the Planned, Forecast and Actual, continue/create a <tr>, then call a template (in the CODE section below) to fill in the data, by matching the package at the beginning of the row, and the column
The questions are these:
- Is there anything to be gained by replacing this structure with <apply-templates> rather than with <call-templates> and <for-each>
- Is it possible to lookup 'vertically' or pass a param somehow (or a sequence thereof) to obtain the steps (IDs) list for filtering the dates?
> Currently, my template relies on each date being created in order (within the Dates table), for correct display, and also doesn't account for missing values (i.e. a date for step 5 being entered without having a date for step 4) so mis-alignments w.r.t the column headers occur.
> I've tried using a nested for-each (selecting the relevant steps then the relevant dates) but the resulting processing causes my SPD to eat up 100's of MBs and slow to a halt.
<xsl:template name="main_table.pfa">
<xsl:param name="PFA"/>
<xsl:param name="Pkg"/>
<td class="style1" style="width: 13px">
<xsl:value-of select="substring($PFA,1,1)"/>
</td>
<xsl:for-each select="$Dates[@Package = $Pkg and @DateType = $PFA]">
<td class="style1" nowrap="nowrap">
<xsl:value-of select="ddwrt:FormatDateTime(string(@DateValue) ,1033 ,'dd-MMM-yy ')"/>
</td>
</xsl:for-each>
</xsl:template>
steps.JPG
ASKER
Clarifications:
- The $PFA parameter is either 'Planned', 'Forecast' or actual and only the first Character is kept to generate the 'P', 'F' and 'A' in the second column
- By 'lookup vertically', I mean for each cell match not only the outer and inner rows (Package & P/F/A) but also the step which is in the <th> element above. I was thinking of perhaps generating a sequence in the template which gets the column headers from the Steps list, by redesigning the template to be recursive.
(current non-recursive header generator in code below)
Basically in the steps list, there is an int column enumerating which steps appear in the view and in what order. others are labelled 'N/A'
Replies:
I'm not exactly sure what your substring() is doing? I'm assuming you think that PFA is a date? (See clarification above). For the sorting of dates, the problem is that they'd need to be sorted by the 'Step' whose ID is part of the record, since you may end up with a step which is completed before the previous (step4.date > step5.date).
Do you know any good, clear example/explanation of proper implementation of a apply-templates? The one on w3schools is not elaborate enough for me to fully grasp how it effectively replaces a for-each.
Thanks in advance for any insight provided.
- The $PFA parameter is either 'Planned', 'Forecast' or actual and only the first Character is kept to generate the 'P', 'F' and 'A' in the second column
- By 'lookup vertically', I mean for each cell match not only the outer and inner rows (Package & P/F/A) but also the step which is in the <th> element above. I was thinking of perhaps generating a sequence in the template which gets the column headers from the Steps list, by redesigning the template to be recursive.
(current non-recursive header generator in code below)
Basically in the steps list, there is an int column enumerating which steps appear in the view and in what order. others are labelled 'N/A'
Replies:
I'm not exactly sure what your substring() is doing? I'm assuming you think that PFA is a date? (See clarification above). For the sorting of dates, the problem is that they'd need to be sorted by the 'Step' whose ID is part of the record, since you may end up with a step which is completed before the previous (step4.date > step5.date).
Do you know any good, clear example/explanation of proper implementation of a apply-templates? The one on w3schools is not elaborate enough for me to fully grasp how it effectively replaces a for-each.
Thanks in advance for any insight provided.
<xsl:template name="main_table.colheaders">
<xsl:for-each select="$Steps">
<xsl:if test="@Rpt_RFPShed != 'N/A'">
<th class="style1">
<xsl:value-of select="@Title"/>
</th>
</xsl:if>
</xsl:for-each>
</xsl:template>
ASKER
I'm still not clear on how the templates are actually called in the example on the page provided?
is it because there is no '/' template that the second most general is matched? By that logic, I'd need to have a match="/" template in order for the others not to be matched, except when called by apply-templates?
does that sound right?
is it because there is no '/' template that the second most general is matched? By that logic, I'd need to have a match="/" template in order for the others not to be matched, except when called by apply-templates?
does that sound right?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
<xsl:for-each select="$Dates[@Package = $Pkg and @DateType = $PFA]">
<xsl:sort select="substring($PFA, 1, 4)" data-type="number"
order="descending"/>
<xsl:sort select="substring($PFA, 6, 2)" data-type="number"
order="descending"/>
<xsl:sort select="substring($PFA, 9, 2)" data-type="number"
order="descending"/>
i don´t understand what you mean by "Is it possible to lookup 'vertically'"
if you are using a nested for-each, then apply-templates is a better solution for perfomance, because it only compiles the loop once.