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

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 14:44:43 -0400 (EST)
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

Thanks again :)

Xiaocun Xu

> -----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

 XSL-List info and archive:

Current Thread