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

Re: Dynamic numbering of lists in xslt

Subject: Re: Dynamic numbering of lists in xslt
From: xslt.new <xslt.new@xxxxxxxxx>
Date: Wed, 10 Jan 2007 11:26:18 -0600
stylesheet xsl fo
Hello All:

I finally got this to work with <xsl:number>.Thanks a lot! This works
great for XSLT.

I am trying to use a similar logic for another module that I am
working on. Here, there are two parameters are passed adhoc thru the
style sheet, and based on these values, I need to use a numberd list
but this time using XSLFO and not XSLT. (I am using renderx as the FO
processor)

I have two parameters: place and time which are passed adhoc to the
style sheet. My input
xml is
<travel1>
<location
<place>NY<place>
<time>EST</time>
</location>
   <travel2>
<location
<place>CaL<place>
<time>PST</time>
</location>
</travel2>
</travel1>
<travel1>
<location
<place>Chi<place>
<time>CST</time>

</location>
</travel1>
<travel1>
<location
<place>NY<place>
<time>EST</time>

</location>
</travel1>
the place and time are passed adhoc to the style sheet. So if place=NY
and time=EST, then the first <travel1> node and the third<travel1>
node should be displayed in a sequenctial order. I am using
fo:list-item-block and <xsl:number> to number the nodes.
My desired output is:
1. NY, EST
2. NY, EST

But since my logic is only on the style sheet and the XML still
contains all the three <travel1> nodes, i get an output like this:

1. NY, EST
3. NY, EST.

so my XSLFO is:

<xsl:template match="travel1">

<xsl:choose>

<xsl:when test=".//location">
<xsl:if test=".//location/place=$place and .//location/time=$time">
<fo:list-block space-before="6pt" space-before.conditionality="retain">
	<fo:list-item>
		<fo:list-item-label end-indent="label-end()">
			<fo:block>
				<xsl:number format="1"/>
			</fo:block>
		</fo:list-item-label>
		<fo:list-item-body start-indent="body-start()" end-indent="0pt">
			<fo:block>
				<xsl:apply-templates/>
			</fo:block>
		</fo:list-item-body>
	</fo:list-item>
</fo:list-block>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:template>

This template is repeated for elment <travel2> as well. <travel2> is a
child of <travel1>.

So, the <fo:list-item>.

<fo:list-block space-before="6pt" space-before.conditionality="retain">
	<xsl:if test="location/environment=$environment and location/company=$company">
		<fo:list-item>
			<fo:list-item-label end-indent="label-end()">
				<fo:block>
					<xsl:number format="1"/>
				</fo:block>
			</fo:list-item-label>
			<fo:list-item-body start-indent="body-start()" end-indent="0pt">
				<fo:block>
					<xsl:apply-templates/>
				</fo:block>
			</fo:list-item-body>
		</fo:list-item>
	</xsl:if>
</fo:list-block>

does not give a sequential list, and skips the nodes in between that
do not match the criteria.

Please let me know if any of this is achievable in XSLFO using renderx.


On 1/9/07, Abel Braaksma <abel.online@xxxxxxxxx> wrote:
David Carlisle wrote:

>>    <xsl:number />  <!-- will only count the matches consecutively -->
>
> Nope, it will number according to the input tree (but the advice to use
> templates rather than a xsl:choose stricture is good)

You are right, of course. Using position(), you can change this behavior
through the apply-templates. Using the input from the OP, and my
approach, the following is a way to do it (using xslt 2 for ease of use
and not needing an input doc, call it on itself)

<xsl:stylesheet
    version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

    <xsl:variable name="source">
        <chapter1>
            <section>first section</section>
        </chapter1>
        <chapter1>
            <section>second section</section>
        </chapter1>
        <chapter1>
            <section>third section</section>
        </chapter1>
        <chapter1>
            <section>fourth section</section>
        </chapter1>
    </xsl:variable>

    <xsl:template match="/">
        <xsl:apply-templates
            select="$source/chapter1[not(section = 'second section')]" />
    </xsl:template>

    <xsl:template match="chapter1">
        <chap>
            <xsl:value-of select="concat(position(), '. ', section)" />
        </chap>
    </xsl:template>

</xsl:stylesheet>

Output:
<chap>1. first section</chap>
<chap>2. third section</chap>
<chap>3. fourth section</chap>


However, if the select-statement becomes more complex, other approaches may be better (not meaning xsl:choose). In addition, if XSLT 2.0 were an option, the select-attribute could be used to achieve the same goal.

If Saxon extensions can be used, an easy (but unwanted) quick fix is to
use saxon's assignable variables.

-- Abel

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.