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

RE: [newbie]use of xsl:if {RE: XSL to handle display mutiple

Subject: RE: [newbie]use of xsl:if {RE: XSL to handle display mutiple pages}
From: "Xu, Xiaocun" <XXu@xxxxxxxxxxxxxxxxxx>
Date: Fri, 3 Nov 2000 16:53:23 -0400 (EST)
xsl top 100 break
Hi, Jeni:

	Much appreciated for the solution you have described.  I applied it
and it worked brilliantly!!
	The only minor thing is, with:
		". | following::item[position() &lt; $maxItemsPage]"
it was displaying one extra item on each page (1-51, 51-101, etc.).  As I
understand the logic, it should have worked.  But instead I had to use:
		". | following::item[position() &lt; ($maxItemsPage - 1)]" 
to get what I wanted (1-50,51-100, etc.)
	Why this is the case?

Much thanks,

Xiaocun Xu
xxu@xxxxxxxxxxxxxxxxxx

> -----Original Message-----
> From: Jeni Tennison [mailto:mail@xxxxxxxxxxxxxxxx]
> Sent: Friday, November 03, 2000 5:36 AM
> To: Xu, Xiaocun
> Cc: ''XSL-List@xxxxxxxxxxxxxxxx' '
> Subject: Re: [newbie]use of xsl:if {RE: XSL to handle display mutiple
> pages}
> 
> 
> Xiaocun,
> 
> >  I started working on XSL to handle display mutiple pages 
> in HTML.  The
> >idea I tried was simple, count number of records until max 
> records per page
> >reaches.  At that time, I close of the current page/table, 
> add a page break
> >and start the next page/table.  But such logic seems does 
> not seems to be
> >allowed in xsl blocks such as xsl:if.  What can be done to 
> get around this
> >problem?
> 
> You are thinking in a procedural way about creating text 
> within an output
> file.  In XSLT, you are *not* creating text within an output 
> file, you are
> creating a node tree, so you *don't* create start tags and 
> end tags, you
> *do* create elements, and you *don't* put the name of an 
> attribute, then a
> equals sign, then a quote, then the attribute value, then 
> another quote,
> you *do* create attributes.
> 
> You need to have that shift in understanding about how XSLT 
> works before
> you're able to use it properly: it will continue to be a frustrating
> language for you to use until you make that shift.
> 
> In XSLT terms, what you want to do is create a number of 
> tables, each of
> which contains a certain number of items.  So, given that the 
> items that
> you want in a single table are stored in the variable $items, you want
> something like:
> 
>   <div style="page-break-before: always" />
>   <table width="100%" border="1" cellspacing="0">
>     <xsl:apply-templates select="tableheader" />
>     <tbody>
>       <xsl:apply-templates select="$items" />
>     </tbody>
>   </table>
> 
> There is no keeping track of how many items there are: you only select
> those items that should be included in the particular table.
> 
> In fact this problem is quite a complex one for someone who is still
> thinking procedurally, so I'll try to take you through it 
> quite slowly step
> by step.
> 
> The main problem is how to identify what items need to go in 
> a particular
> table.  You know the number of items that you want per page
> ($maxItemsPage), so you know that every $maxItemsPage + 1st 
> item is the top
> of each page (if $maxItemsPage is 5, then the 1st, 6th, 11th and so on
> items start each table).  This means that you can work out 
> which items are
> those that go at the top of the page using 'mod'.  If the 
> number of the
> item, mod the number of items of the page, equals 1, then you 
> have an item
> at the start of the page.  So, for these items, the test expression:
> 
>   (position() mod $maxItemsPage) = 1
> 
> will be true.  This means you can select all those items 
> using the select
> expression:
> 
>   //item[(position() mod $maxItemsPage) = 1]
> 
> Once you have one of these items, then you know the rest of 
> the items that
> are on the page, because you know there will be $maxItemsPage 
> - 1 of them
> (the one you have, plus $maxItemsPage - 1 more gives you 
> $maxItemsPage in
> total).  In other words, if you built a list of all the items that are
> after the item you currently have, and then just took those 
> whose position
> within that list was less than $maxItemsPage, then you'd get 
> the rest of
> the items for the page.  Building the list involves getting all the
> following items:
> 
>   following::item
> 
> and then testing whether their position is less than 
> $maxItemsPage involves
> the test:
> 
>   position() &lt; $maxItemsPage
> 
> so the XPath is:
> 
>   following::item[position() &lt; $maxItemsPage]
> 
> So, if we have a template that matches one of those items 
> that will appear
> at the top of the page, then the items that make up the page 
> are (a) the
> current item and (b) the next $maxItemsPage - 1 items.  These 
> are unioned
> together with the '|' operator.  The '.' means 'the current node'.
> 
>   . | following::item[position() &lt; $maxItemsPage]
> 
> So, the template will look something like:
> 
> <!-- matches the top items in a page -->
> <xsl:template match="item" mode="top">
>   <!-- works out what items will go on the page -->
>   <xsl:variable name="items"
>                 select=". | following::item[position() &lt; 
> $maxItemsPage]" />
>   <!-- put in the page break -->
>   <div style="page-break-before: always" />
>   <!-- add the table -->
>   <table width="100%" border="1" cellspacing="0">
>     <xsl:apply-templates select="tableheader" />
>     <tbody>
>       <xsl:apply-templates select="$items" />
>     </tbody>
>   </table>
> </xsl:template>
> 
> [Note that the above is largely taken from your code: I don't 
> know whether
> the tableheader elements are really children of 'item' 
> elements - if not
> then no table header will be given.]
> 
> The only thing that it remains to do is make sure that templates are
> applied to only those items that appear at the top of the 
> page, and using
> the 'top' mode that we've used for the template.  Recall that 
> the top items
> could be selected with the expression:
> 
>   //item[(position() mod $maxItemsPage) = 1]
> 
> So, given this, you can apply templates to those with:
> 
>   <xsl:apply-templates select="//item[(position() mod 
> $maxItemsPage) = 1]"
>                        mode="top" />
> 
> I hope that this helps, and shows how the declarative 
> approach works in a
> case like this.  If you need any more help on the details, please give
> examples of the source XML that you're using and the result 
> that you want.
> 
> Cheers,
> 
> Jeni
> 
> Jeni Tennison
> http://www.jenitennison.com/
> 




 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.