xsl-list
[Top] [All Lists]

Re: Key and/or grouping questions.

2002-12-05 15:39:07
"Edward L. Knoll" wrote:

I have a set of style sheets which have a sever performance
problem. Distilled (hopefully not diluted past usefulness), I
am processing a
large set of sibling elements a few elements at a time.   I
believe the
problem is with the following statement (which I've
changed/condensed the expression of):

<xsl:for-each  select="/elements[ (position() &gt;= $Start) and
(position() &lt;= $End) ]">
...
</xsl:for-each>

I suspect it actually starts "//elements", because you can't have more
than one element that's a child of the root node. But the fact that
position() works suggests that they are siblings. Without seeing your
source, the first step might be to change this to /*/elements[...]. The
next step would be to create a global variable whose value is
/*/elements, and replace the for-each by

select="$var[position() ...]

I was referred to a FAQ on grouping and this led me to
attempt to setup
some kind of solution utilizing keys.   Unfortunately, the
XSL reference
I have has no information on <xsl:key> and my favorite FAQ
has a list of topics under keys with no corresponding
content.  Anyway, my XSL processor (Xalan) doesn't like my
key definition.  Is the "use" parameter limited from being a
numerical expressions?

<xsl:key name="PageKey" match="/gnsl:Results/gnsl:Table/gnsl:Row"
         use="((position() - 1) / $RowsPerPage) + 1)" />


It helps in any XPath expression to balance the parentheses properly.

But your problem here is misunderstanding what "position()" means. It
means the position of the context node in the sequence of nodes
currently being processed. In <xsl:key> it will always be 1.

What you want is something like:

   use="count(preceding-sibling::*)"

But I suspect this may not help you, because it's likely to be very
expensive to build this index.

I think a better approach would be to restructure your code to use the
usual:

<xsl:for-each select="xx[position() mod $size = 1]">
  ..
  <xsl:for-each select=".|following-sibling[position() &lt;= $size]">

Trying something similar to the nested for-each, excpet my outer
for-each is somthing similar to the following:

   <xsl:for-each select="xx[position() = $startPos]">

I get the line at the starting postion just fine, but I get none of the
following-sibling elements.  If the outer loop selects one element (or
even every nth element), are the elements selected by the outer loop
going to have siblings other than those selected by the outer loop; I'm
guessing not.  I suspect the inner loop in the algorithm above is going
to process a number nodes equal to $size, but those nodes will be every
nth element from the xx where n = $size.

If I've missed something, please let me know.

Syntax error again; the following works:

  <xsl:for-each select=".|following-sibling::*[position() &lt;= $size]">

-- 
Edward L. Knoll   Phone (work)     : (719)484-2717
                  e-mail (work)    : 
ed(_dot_)knoll(_at_)cosd(_dot_)fedex(_dot_)com
                  e-mail (business): eknoll(_at_)sf-inc(_dot_)com
                  e-mail (personal): edward(_at_)elknoll(_dot_)com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list