xsl-list
[Top] [All Lists]

[xsl] xpath key problems: follow-up

2010-11-25 15:43:13
Dear XSLT List,

Thanks to those who replied to my inquiry about keys and grouping. To follow up:

1. As Piet pointed out, I had swapped the @match and @use values, confusing 
whether I was specifying what was being used when the key was constructed with 
what was used when it was called. Sigh.

2. As Martin pointed out, I had also confused what was being passed by the 
<xsl:key> element. I had thought it was the element itself (that is, the 
element object), while it was actually the atomized string value of the 
element. I would have needed Piet's strategy of using generate-id to construct 
a pointer to the element.

3. Keys pay off when reused, but if I'm going to access each value only once, 
there's no economy in doing that by constructing a key as opposed to doing it 
in the template itself.

4. I had originally constructed an XPath that collected the preceding elements 
that had the same name value as the current one and then looked inside them for 
<pb> elements. This was unacceptably slow, but I got an responably peppy 
response by instead collecting the preceding <pb> elements and then using a 
predicate to filter out the ones that have a different parent than the current 
element:

        preceding::pb[parent::*[name() eq current()/name()]][1]/@folio  

5. Counting lines (<lb> elements) from the most immediately preceding <pb> 
through the current position required a compound predicate that specified three 
things:

        a. Before the current position. Use the preceding axis.
        b. After the most immediately preceding page break. Use the <pb> 
identified above.
        c. Same parent as the current element. Specify this in the predicate.

Put together:

    <xsl:template match="hm280 | hm281 | hm282">
        <!-- $foliopointer is the most immediate preceding pb
            requires special treatment for first line, which has no preceding 
pb -->
        <xsl:variable name="foliopointer"
            select="if (preceding::block) then preceding::pb[parent::*[name() 
eq current()/name()]][1]/@folio
            else pb/@folio"/>
        <!-- $linepointer is count of lb elements between $foliopointer and
            current position -->
        <xsl:variable name="linepointer"
            select="1 + count(preceding::lb[parent::*[name() eq 
current()/name()] and 
            preceding::pb[parent::*[name() eq current()/name()]][1]/@folio eq 
$foliopointer])"/>

This lets me generate the page/line identifiers I need. Thanks again to those 
whose responses pushed me back on the right track.

Sincerely,

David (djbpitt(_at_)pitt(_dot_)edu) 


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>
  • [xsl] xpath key problems: follow-up, Birnbaum, David J <=