[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Keeping an eye on processed nodes

Subject: Re: Keeping an eye on processed nodes
From: "J.Pietschmann" <j3322ptm@xxxxxxxx>
Date: Wed, 15 Jan 2003 23:57:03 +0100
eye nodes
Gustaf Liljegren wrote:
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>&#xA;  </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 &gt;= $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.

J.Pietschmann


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.