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