Subject: RE: [newbie]use of xsl:if {RE: XSL to handle display mutiple page s} From: "Xu, Xiaocun" <XXu@xxxxxxxxxxxxxxxxxx> Date: Fri, 3 Nov 2000 16:53:23 -0400 (EST) |
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() < $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() < ($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() < $maxItemsPage > > so the XPath is: > > following::item[position() < $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() < $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() < > $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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [newbie]use of xsl:if {RE: XSL , Xu, Xiaocun | Thread | Re[2]: [newbie]use of xsl:if {RE: X, Jeni Tennison |
XSL-List is unmoderated, XSL-List Owner | Date | how to number on a grouped and sort, Chad Small |
Month |