xsl-list
[Top] [All Lists]

Re: Key and/or grouping questions.

2002-12-05 08:48:49

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 actually use a global variable to contain the list of elements.  I
knew I was going to get into problems attempting to abbreviate my
descriptions.

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.

I was wondering if that might be the case; I was hoping that since the
"match=..." term was representing the entire set of Rows, that the
actual key processing would have been processing the set all at once. 
The only thing that confuses me is that if this is the case all my Row
elements should have had a key value of '1' and they all should have
shown up on the first page.  To date I have been eniterly unsuccessful
at accessing anything through this key.  

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.

If this worked, it would actually be much more efficient for my
worst-case performance scenario.  I think I'll try it just to see what
happens.

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]">

Doesn't really fit my processing model, but with all good suggestions
it's stimulating me to consider some other solution directions.  I
really only need to  find the first Row; I can use the following-sibling
axis to access the remainder.  Definitely some good food for thought.

Thanks,
Ed Knoll


Michael Kay
Software AG
home: Michael(_dot_)H(_dot_)Kay(_at_)ntlworld(_dot_)com
work: Michael(_dot_)Kay(_at_)softwareag(_dot_)com 


-- 
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