This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: [newbie]use of xsl:if {RE: XSL to handle display mutiple pages}
- To: "'Jeni Tennison'" <mail at jenitennison dot com>
- Subject: RE: [newbie]use of xsl:if {RE: XSL to handle display mutiple pages}
- From: "Xu, Xiaocun" <XXu at CommercialWare dot com>
- Date: Fri, 3 Nov 2000 14:44:43 -0400 (EST)
- Cc: "''XSL-List at mulberrytech dot com' '" <XSL-List at mulberrytech dot com>
- Reply-To: xsl-list at mulberrytech dot com
Hi, Jeni:
Thanks for taking out time for such a detailed walkthrough, much
appreciated :) Yeah, this is a complicated problem for me. My previous
dealing with XSL were much simpler so I did not have to venture this deep.
I will have to take some time to absorb all these knowledge and understand
it.
Thanks again :)
Xiaocun Xu
xxu@commercialware.com
> -----Original Message-----
> From: Jeni Tennison [mailto:mail@jenitennison.com]
> Sent: Friday, November 03, 2000 5:36 AM
> To: Xu, Xiaocun
> Cc: ''XSL-List@mulberrytech.com' '
> 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