Subject: Re: [xsl] Keeping an eye on processed nodes From: "J.Pietschmann" <j3322ptm@xxxxxxxx> Date: Wed, 15 Jan 2003 23:57:03 +0100 |
...I'm doing something really wrong here. I'm trying to process an index for a book, and find myself in a situation where I need to keep an eye on which nodes I have already processed. Since this is not possible in XSLT, I need your help to find an alterntive solution. Part of the XML:
<?xml version="1.0" encoding="iso-8859-1"?> <index> ... <entry page="34">A4 page size</entry> <entry page="37">absolute direction</entry> <entry page="172" context="absolute-position property">correcting content position with</entry> <entry page="91" context="absolute-position property">offsetting content with</entry> <entry page="139">alignment points</entry> ... </index>
The problem occurs when several words are grouped.
Well, "grouping" is the key, of course. Search the XSL FAQ for details. I think you'll have to group by text content and context, something like <xsl:key name="group" match="entry" use="concat(text(),'@',@context)"/>
<xsl:template match="index"> <xsl:for-each select="entry(generate-id()= generate-id(key('group',concat(text(),'@',@context))[1])"> <xsl:sort select="text()"/> <xsl:value-of select="text()/> <xsl:if test="@context"/> <xsl:text>
 </xsl:text> <xsl:value-of select="@context/> </xsl:test> <xsl:for-each select="key('group',concat(text(),'@',@context))> <xsl:sort seletc="@page"/> <xsl:value-of select="@page"/> <xsl:text>, </xsl:text> </xsl:for-each> </xsl:for-each> </xsl:template>
Processing runs of consecutive page numbers into the page range notation can be a bit tricky unless the page numbers are already sorted in the input, otherwise you'll probably have to use the xx:node-set() extension to produce a sorted node set. Once you have this, use a recursive template to detect runs. Another possiblity could be really clever selection <xsl:for-each select="entry[ previous-sibling::entry[1]/@page!=@page - 1" and following-sibling::entry[1]/@page=@page + 1 and following-sibling::entry[2]/@page=@page + 2]"> <!-- start of a run of more than two consecutive page numbers --> <xsl:variable name="startpage" select="@page"/> <xsl:value-of select="$startpage"/> <xsl:text>-</xsl:text> <xsl:value-of select="following-sibling::entry[ @page=$startpage + count(previous-sibling::entry [@page >= $startpage])][last()]/@page"/> </xsl:for-each>
Beware, untested. Look for boundary problems, off-by-one errors etc. I also expect a recursive template solution to be more efficient, probably noticably so if long runs of consecutive page numbers occur often.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Keeping an eye on processed n, Gustaf Liljegren | Thread | RE: [xsl] Keeping an eye on process, Ross Ken |
RE: [xsl] Register Marks, Funny Cha, Ross Ken | Date | Re: [xsl] Docbook html:form How to , Jirka Kosek |
Month |