Subject: [xsl] Sibling axis: All of kind A up to first of kind B From: Michael Ludwig <mlu@xxxxxxxxxxxxx> Date: Tue, 25 Mar 2008 19:35:50 +0100 |
<html> <h1>Eins</h1><p>Bla bla</p> <h2>Zwei</h2><p>Bla bla bla</p> <h2>Drei</h2><p>Bla bla blub</p> <h1>Vier</h1><p>Bla bla</p> <h2>Fuenf</h2><p>Bla bla bla</p> <h2>Sechs</h2><p>Bla bla</p> </html>
I want to add something to this document. I want each h1 header to be followed by a listing of its respective h2 headers, like a summary. (You'll then know straight away what's in the subsections.) This can be done using both sibling axes, first forward, then backward.
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="h1"> <xsl:copy-of select="."/> <div class="toc"><!-- subheadings of current h1 --> <xsl:apply-templates select="following-sibling::h2[ generate-id(preceding-sibling::h1[1]) = generate-id(current()) ]"/> </div> </xsl:template> <xsl:template match="@*|node()"><!-- copy template --> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:transform>
This works fine. But is it efficient? Or is there a better way to do this in XSL 1.0? If there were zillions of those headers, would the processor then have to backtrack at each h2 in order to find the first h1 in reverse document order and do the comparison? Or are implementations required to be smarter than that so the user doesn't have to care about these details?
How could I instruct the processor most efficiently to process all h2 headers but only so long as there is no h1 header encountered on the way, the way being the following-sibling axis?
The other day, "sibling recursion" was mentioned on this list. Does the following qualify as sibling recursion - and is this likely to be more efficient for large input?
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="h1"> <xsl:copy-of select="."/> <div class="h1toc"><!-- subheadings of current h1 --> <xsl:apply-templates mode="toc" select="(following-sibling::h1 | following-sibling::h2)[ 1 ]"/> </div> </xsl:template> <xsl:template match="h1" mode="toc"/><!-- stop on h1 --> <xsl:template match="h2" mode="toc"><!-- copy and continue --> <xsl:copy-of select="."/> <xsl:apply-templates mode="toc" select="(following-sibling::h1 | following-sibling::h2)[ 1 ]"/> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:transform>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XSLT 2.0 in a web browser, bryan rasmussen | Thread | RE: [xsl] Sibling axis: All of kind, Michael Kay |
Re: [xsl] XPath 2.0 Best Practice: , Martin Honnen | Date | RE: [xsl] Selecting unparsed text f, Angela Williams |
Month |