Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to display a fixed number of elements? 2

Status
Not open for further replies.

BeckD

Programmer
Apr 16, 2002
53
0
0
GB
Hi

I have an xml page which is database driven (asp). In my xsl page I only want to display the first 5 articles. Something like:

--xml page
<page>
<article>
<title>Test</title>
<body>blah blah blah labhabl hb</body>
</article>
<article>
<title>Test</title>
<body>blah blah blah labhabl hb</body>
</article>
<article>
<title>Test</title>
<body>blah blah blah labhabl hb</body>
</article>
<article>
<title>Test</title>
<body>blah blah blah labhabl hb</body>
</article>
--etc
</page>

--xsl - this bit only wants to select the first 5 articles although the code I've put doesn't work
<xsl:for-each select=&quot;/page/article[count = 5]&quot;>
<xsl:value-of select=&quot;title&quot; />
</xsl:for-each>

If you get my drift...

I have found an example which works with the working draft xsl namespace, but it won't work with the namespace I'm using (<xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot; and I don't really want to go backwards and use the working draft. This code is:

<xsl:choose>
<xsl:when expr=&quot;childNumber(this) > 5&quot;></xsl:when>
<xsl:eek:therwise>
<xsl:value-of select=&quot;/page/article/title&quot; />
</xsl:eek:therwise>
</xsl:choose>

Grateful in advance for any comments/suggestions...
 
try:


<xsl:for-each select=&quot;/page/article&quot;>
<xsl:choose>
<xsl:when expr=&quot;count() > 5&quot;></xsl:when>
<xsl:eek:therwise>
<xsl:value-of select=&quot;title&quot; />
</xsl:eek:therwise>
</xsl:choose>
<xsl:for-each>

... you're lagging it a bit by doing nothing for the rest of the cycles but at least it should work...

You cant do for-each select=&quot;/page/article[count() > 5]&quot; because [] indicates node expressions and directly correlates to the nodes you are selecting, not the context within which you are working (unlike count, which is only operational within a context).

Another, more processor friendly way to do it, is to provide an identifying tag within your xml with which you can display a range of data from, eg:

<page>
<article number=&quot;1&quot;>
<title>Test</title>
<body>blah blah blah labhabl hb</body>
--etc
</page>


and then provide the template

<xsl:template select=&quot;//article[@number < 5]&quot;>
<xsl:value-of select=&quot;title&quot;/>
</xsl:template>

.. this should do unless you are dynamically updating or randomly updating articles within the xml.

hope this helps, let me know if you have any other questions :)

matt

 
Hi Matt

Thanks for your help, but I get the following error:

msxml3.dll error '80004005'

Attribute 'expr' is invalid on 'xsl:when'.

/xml/index.asp, line 68

(NB: index.asp line 68 is an asp file which parses the xml and xsl file)
 
ag, i cut and paste your example in and forgot that the /transform namespace in when doesnt support expr! :(

it should be

<xsl:for-each select=&quot;/page/article&quot;>
<xsl:choose>
<xsl:when test=&quot;count() > 5&quot;></xsl:when>
<xsl:eek:therwise>
<xsl:value-of select=&quot;title&quot; />
</xsl:eek:therwise>
</xsl:choose>
<xsl:for-each>

soz
 
plus make sure you use & gt; instead of an &quot;>&quot;!!!
 
I'm still getting an error: -

msxml3.dll error '80004005'

Expression expected. count(-->)<-- > 5

/xml/index.asp, line 68

Just to check with you that I'm not doing anything stupid, here's the code I'm using:

<xsl:for-each select=&quot;/page/article&quot;>
<xsl:choose>
<xsl:when test=&quot;count() > 5&quot;></xsl:when>
<xsl:eek:therwise>
<p><span class=&quot;headline&quot;><xsl:value-of select=&quot;title&quot;/></span></p>
</xsl:eek:therwise>
</xsl:choose>
</xsl:for-each>
 
doh.

put a '.' inside the brackets of count(), eg &quot;[count(.) > 5]&quot;

that should do it.

(mental note, always check your answers before posting :)

 
Sorry Matt - it still doesn't work. Am now getting:

msxml3.dll error '80004005'

Expression expected. <--

/xml/index.asp, line 68

I've tried putting:

<xsl:when test=&quot;count(.) > 5&quot;></xsl:when>
or
<xsl:when test=&quot;count(/page/article) > 5&quot;></xsl:when>
or
<xsl:when test=&quot;[count(.) > 5]&quot;></xsl:when>

and I get the same error with all.


 
are you using & gt; (remove the space) and not > in your expression? This is my working example on my debugger:

<xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot; <xsl:template match=&quot;/&quot;>

<xsl:for-each select=&quot;/page/article&quot;>
<xsl:choose>
<xsl:when test=&quot;count(.) & gt; 5&quot;></xsl:when>
<xsl:eek:therwise>
<p>
<span class=&quot;headline&quot;>
<xsl:value-of select=&quot;title&quot;/>
</span>
</p>
</xsl:eek:therwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Remember to remove the space if you cut n paste this from & gt; ..

matt
 
AGGGG

dont use count(.) use position().


so sorry about that. its monday :(

 
Try This one
XML:
<?xml version=&quot;1.0&quot; ?>
<table>
<row>Row#1</row>
<row>Row#2</row>
<row>Row#3</row>
<row>Row#4</row>
<row>Row#5</row>
<row>Row#6</row>
<row>Row#7</row>
<row>Row#8</row>
<row>Row#9</row>
<row>Row#10</row>
</table>

XSL:
<?xml version=&quot;1.0&quot;?>
<xsl:stylesheet version=&quot;1.0&quot;
xmlns:xsl=&quot; <xsl:eek:utput method=&quot;html&quot; encoding=&quot;Windows-1252&quot; />
<xsl:param name=&quot;Page&quot; select=&quot;2&quot; />
<xsl:param name=&quot;PageSize&quot; select=&quot;5&quot; />
<xsl:template match=&quot;table&quot;>
<html>
<head></head>
<body>
<xsl:variable name=&quot;RowCount&quot; select=&quot;count(row)&quot; />
<xsl:variable name=&quot;Pages&quot; select=&quot;ceiling($RowCount div $PageSize)&quot; />
<xsl:variable name = &quot;page&quot;>
<xsl:choose>
<xsl:when test=&quot;($Page > $Pages) or ($Page <= 0)&quot;>1</xsl:when>
<xsl:eek:therwise><xsl:value-of select=&quot;$Page&quot; /></xsl:eek:therwise>
</xsl:choose>
</xsl:variable>
Number Of Rows
<xsl:value-of select=&quot;$RowCount&quot; />
<BR />

Total Pages =
<xsl:value-of select=&quot;$Pages&quot; />

<xsl:for-each select=&quot;row[(position() <= $PageSize * $page and position() > $PageSize * ($page -1 ))]&quot;>
<div><xsl:value-of select=&quot;.&quot; /></div>
</xsl:for-each>

<xsl:call-template name=&quot;for.loop&quot;>
<xsl:with-param name=&quot;i&quot;>1</xsl:with-param>
<xsl:with-param name=&quot;count&quot; select=&quot;$Pages&quot; />
<xsl:with-param name=&quot;current&quot; select=&quot;$page&quot; />
</xsl:call-template>
</body>
</html>
</xsl:template>

<xsl:template name=&quot;for.loop&quot;>
<xsl:param name=&quot;i&quot; />

<xsl:param name=&quot;count&quot; />

<xsl:param name=&quot;current&quot; />

<xsl:if test=&quot;$i <= $count&quot;>
<xsl:choose>
<xsl:when test=&quot;$i != $current&quot;><xsl:value-of select=&quot;$i&quot; /></xsl:when>
<xsl:eek:therwise><b><xsl:value-of select=&quot;$i&quot; /></b></xsl:eek:therwise>
</xsl:choose>
<xsl:if test=&quot;$i+1 <= $count &quot;>,</xsl:if>
</xsl:if>
<xsl:if test=&quot;$i <= $count&quot;>
<xsl:call-template name=&quot;for.loop&quot;>
<xsl:with-param name=&quot;i&quot; select=&quot;$i + 1&quot; />
<xsl:with-param name=&quot;count&quot; select=&quot;$count&quot; />
<xsl:with-param name=&quot;current&quot; select=&quot;$current&quot; />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
------------------------------
 
anything you want, if you change the XML Nodes, do the same with XSL.
 
I may be being dumb here, but I don't really understand what you're getting at. If you're tring to do the same thing, then isn't the way that Matt already suggested shorter, simpler and more efficient?
 
Hi,
Pls anybody send me the working copy of xml/xsl paging.
 
how? we dont know your details, mr visitor type person :)
 
i have a question:
could you have done something like

<xsl:for-each select=&quot;/page/article[position()<5]&quot;>
<xsl:value-of select=&quot;title/>
</xsl:for-each>

wouldn't this be faster than iterating through every article and evaluating an expression?

mike griffith
----------------------------
mgriffith@lauren.com
mdg12@po.cwru.edu
 
yes.

erm.

:)

the only drawback would be if you wanted to do something if the value was greater than 5, like display a break or something.

apart from that, thats a nice elegant solution.

I think i must have been half asleep when I answered the original question.. I dont know where my head was at that day :(

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top