Jump to content
andreathedove

paging XML

Recommended Posts

Hello,I am very sorry for this trouble.I have to paging a feed xml with asp and xsl.Here the file that not workhttp://www.allinonenet.it/shopping/prova/prova2.asp?n=1&cat=It print all the feed, but I want 6 per page.The asp code are:

<%@ Language=VBScript %><%' prevent page cachingResponse.CacheControl = "no-cache"Response.AddHeader "Pragma", "no-cache"Response.Expires = -1 cat 	 = Request.QueryString("Cat")number 	 = Request.QueryString("n")xslpath 	 = Server.mappath("page2.xsl")sourceFile 	 = server.MapPath("td.xml")  Set source = Server.CreateObject("Msxml2.DOMDocument")  source.async = false  source.load(sourceFile)set xsldoc  = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")xsldoc.async = falsexsldoc.load(xslpath) set xsltemp = Server.createObject("MSXML2.XSLTemplate")xsltemp.stylesheet=xsldocset xslproc = xsltemp.createProcessorxslproc.input=sourcexslproc.output=Response' parameter for message groupxslproc.addParameter "mastercategoria",Catxslproc.addParameter "pagenumber",numberxslproc.transformResponse.End%>

but the xml and xsl are herehttp://www.allinonenet.it/shopping/prova/td.xmlhttp://www.allinonenet.it/shopping/prova/page2.xslCan you help me?Andrea

Share this post


Link to post
Share on other sites

I'm not exactly sure what are you doing, but to select nodes in range, use this in your XSLT select statement:

/products/product/TDProductId[position() >=1 and position() <=6]

Then, with ASP, make something that would just increase both 1 and 6 by 6 to result in the next page's content being selected.

Share this post


Link to post
Share on other sites
I'm not exactly sure what are you doing, but to select nodes in range, use this in your XSLT select statement:
/products/product/TDProductId[position() >=1 and position() <=6]

Then, with ASP, make something that would just increase both 1 and 6 by 6 to result in the next page's content being selected.

I have not only node TDProductId, for this motive I can not apply them.I don't understand what I should do
Then, with ASP, make something that would just increase both 1 and 6 by 6 to result in the next page's content being selected.

Can yu help me with an example?Andrea

Share this post


Link to post
Share on other sites
I have not only node TDProductId, for this motive I can not apply them.I don't understand what I should do

Use multiple value-of's or templates to output each elemtent that should be paged. Something like this:
<xsl:for-each select="/products/product[position() >=1 and position() <=6]"><xsl:value-of select="TDProductId" /> <br /><xsl:value-of select="name"/> <br /><xsl:value-of select="description"/></xsl:for-each>

Then, with ASP, make something that would just increase both 1 and 6 by 6 to result in the next page's content being selected.

Can yu help me with an example?Andrea

Unfortunatly, no. I can't. I'm not much into XML DOM (yet), nor ASP so I have no idea what code should you use. What I'm saying is just to outline the stuff you should be after. So the ASP code should alter the previous example to turn intoSomething like this:
<xsl:for-each select="/products/product[position() >=7 and position() <=12]"><xsl:value-of select="TDProductId" /> <br /><xsl:value-of select="name"/> <br /><xsl:value-of select="description"/></xsl:for-each>

As you can notice, the ranged values in the for-each statement have changed, which is actually just what you need to show the next page.

Share this post


Link to post
Share on other sites
I'm not exactly sure what are you doing, but to select nodes in range, use this in your XSLT select statement:
/products/product/TDProductId[position() >=1 and position() <=6]

Then, with ASP, make something that would just increase both 1 and 6 by 6 to result in the next page's content being selected.

don't work

Share this post


Link to post
Share on other sites
don't work

Sure it doesn't. Did you saw my second example:
<xsl:for-each select="/products/product[position() >=1 and position() <=6]"><xsl:value-of select="TDProductId" /> <br /><xsl:value-of select="name"/> <br /><xsl:value-of select="description"/></xsl:for-each>

That is the one which should work for the first page to be shown. If you can just make an ASP script to increase 1 and 6 by 6 each time some button is clicked, then it would work perfectly... or maybe not. You'll need to specify the end of the line (the number of all "product"s) somehow, but that's not your worry now.

Share this post


Link to post
Share on other sites
Sure it doesn't. Did you saw my second example:
<xsl:for-each select="/products/product[position() >=1 and position() <=6]"><xsl:value-of select="TDProductId" /> <br /><xsl:value-of select="name"/> <br /><xsl:value-of select="description"/></xsl:for-each>

That is the one which should work for the first page to be shown. If you can just make an ASP script to increase 1 and 6 by 6 each time some button is clicked, then it would work perfectly... or maybe not. You'll need to specify the end of the line (the number of all "product"s) somehow, but that's not your worry now.

Hello,I have this problem and i can not resolve it.If you can take a look in the end of this page, where you can find the paging of the feed with xsl:http://www.allinonenet.it/shopping/prova/xml.asp?n=8&cat=And it don't work.The first problem is: - the page start from 5 instead of 1 - the total page are 3 and not 19 (because the total item in the feed are 15 and div 5 per page = 3 )The xsl code are herehttp://www.allinonenet.it/shopping/prova/xsl.xsland the xml code here:http://www.allinonenet.it/shopping/prova/xml.xmlFor read xml and xsl I use asp.Thanks to all for help me,Andrea

Share this post


Link to post
Share on other sites

It's kind of hard to judge, scince ASP plays so important role in making the application work smoothly, but how about changing all of the

preceding-sibling::*

to

preceding-sibling::.

I mean, the count is different. When the 5th element is processed, the count of the precending siblings is 1+2+3+4 not simply 4. Maybe that's causing the problem.

Share this post


Link to post
Share on other sites
It's kind of hard to judge, scince ASP plays so important role in making the application work smoothly, but how about changing all of the
preceding-sibling::*

to

preceding-sibling::.

I mean, the count is different. When the 5th element is processed, the count of the precending siblings is 1+2+3+4 not simply 4. Maybe that's causing the problem.

I have change, but it give me errohttp://www.allinonenet.it/shopping/prova/xml.asp?cat=:-(

Share this post


Link to post
Share on other sites

Hmm... maybe using current() instead of a dot.

Share this post


Link to post
Share on other sites
not(current(preceding-sibling::.)+1 ... ?

H#ll, no. I meant
preceding-sibling::current()

instead of

preceding-sibling::.

Share this post


Link to post
Share on other sites
H#ll, no. I meant
preceding-sibling::current()

instead of

preceding-sibling::.

ehm, this is the code with your change<xsl:choose><xsl:when test="not(count(preceding-sibling::current()+1 = $pagenumber)"> <a href="?n={count(preceding-sibling::current()+1}&cat={$mastercategoria}"><xsl:value-of select="count(preceding-sibling::current()+1" /></a></xsl:when><xsl:otherwise> <xsl:value-of select="count(preceding-sibling::current()+1" /></xsl:otherwise></xsl:choose>it don't work ...:-(

Share this post


Link to post
Share on other sites
H#ll, no. I meant
preceding-sibling::current()

instead of

preceding-sibling::.

The xsl now work, because the file xml was and rss feed and I trasform it in xml.Now I have the second problem:- the total page are 3 and not 15 (because the total item in the feed are 15 and div 5 per page = 3 )You can help me ?Andrea

Share this post


Link to post
Share on other sites

Well, I think the key might be the way you get your $total variable.

<xsl:variable name="total" select="round(count(*[name() = $element]) div 5) + 1"/>

I seem to be unable to figure out why are you making it more complex then it is... how about simplifying it a bit:

<xsl:variable name="total" select="count(//*[name() = $element]) div $recordsPerPage"/>

I'm not exactly sure what your $element variable is holding, but if I hope it holds the name of the elements you're counting. And that element should be... item. Correct? Unless you're trying to make some sort of recursive template, you could always put the exact XPath right there:

<xsl:variable name="total" select="count(/dataset/item) div $recordsPerPage"/>

Share this post


Link to post
Share on other sites
Well, I think the key might be the way you get your $total variable.
<xsl:variable name="total" select="round(count(*[name() = $element]) div 5) + 1"/>

I seem to be unable to figure out why are you making it more complex then it is... how about simplifying it a bit:

<xsl:variable name="total" select="count(//*[name() = $element]) div $recordsPerPage"/>

I'm not exactly sure what your $element variable is holding, but if I hope it holds the name of the elements you're counting. And that element should be... item. Correct? Unless you're trying to make some sort of recursive template, you could always put the exact XPath right there:

<xsl:variable name="total" select="count(/dataset/item) div $recordsPerPage"/>

... and what change here- <xsl:for-each select="*[name() = $element]">- <xsl:choose>- <xsl:when test="not(count(preceding-sibling::*)+1 = $pagenumber)"> - <a href="?n={count(preceding-sibling::*)+1}&cat={$mastercategoria}"> <xsl:value-of select="count(preceding-sibling::*)+1" /> </a> </xsl:when>- <xsl:otherwise> <xsl:value-of select="count(preceding-sibling::*)+1" /> </xsl:otherwise> </xsl:choose> </xsl:for-each>?

Share this post


Link to post
Share on other sites

Weren't you suppose to change the * into a current()? I'm actually wondering if what I'm looking at above (the XSLT link) is the latest XSLT. I haven't noticed any change :) .[edit] Oh... for starters... try to change:

<xsl:variable name="total" select="round(count(*[name() = $element]) div 5) + 1" />

to

<xsl:variable name="total" select="count(/dataset/item) div $recordsPerPage"/>

If that works, I'll try to generalize the template.[/edit]

Share this post


Link to post
Share on other sites
Weren't you suppose to change the * into a current()? I'm actually wondering if what I'm looking at above (the XSLT link) is the latest XSLT. I haven't noticed any change :) .[edit] Oh... for starters... try to change:
<xsl:variable name="total" select="round(count(*[name() = $element]) div 5) + 1" />

to

<xsl:variable name="total" select="count(/dataset/item) div $recordsPerPage"/>

If that works, I'll try to generalize the template.[/edit]

Hello boen_robot, :) where are the other post?Andrea

Share this post


Link to post
Share on other sites

Don't you know? The forum was hacked, and a backup from july 8th was used to restore the forum, so all posts after july 8th are lost.I've made some major modifications scince the last time, including the latest issue you had, but it's at home and currently, I can't connect to my home computer (my mother has probably turned it off). I'll post the code and the PHP5 page as soon as possible. In the meantime, you might want to post the latest ASP one :) . I hope you implemented the check for whether $pageNumber is a number as I did with the PHP.[edit] What did I said? Yes, I can. Just not now, because it's not on the computer I'm on. [/edit]

Share this post


Link to post
Share on other sites
Don't you know? The forum was hacked, and a backup from july 8th was used to restore the forum, so all posts after july 8th are lost.I've made some major modifications scince the last time, including the latest issue you had, but it's at home and currently, I can't connect to my home computer (my mother has probably turned it off). I'll post the code and the PHP5 page as soon as possible. In the meantime, you might want to post the ASP one :) .
Can you re post the transform lesson with PHP5? :) Andrea

Share this post


Link to post
Share on other sites

Here's the new and all improved XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">	<!--These variables are the easiest to change outside the XSLT-->	<xsl:param name="pageNumber" select="1" />	<xsl:param name="recordsPerPage" select="5" />		<!--It's neccesary to change this in order to use this XSLT.	If you have multiple catalogues with different element names, you can remove this parameter and it's every occurance in this XSLT.	For any other complicated XMLs, there will be a need for a lot more complex editings.-->	<xsl:param name="pagedElement" select="'item'" />	<!--With this thing, you don't need to change anything if the pagedElement is just below the root element.-->	<xsl:param name="totalRecords" select="count(/*/*[name()=$pagedElement])"/>	<xsl:param name="totalPages" select="ceiling($totalRecords div $recordsPerPage)"/>		<!--This is the place to turn all or some of the controls off.	You can easily do that even outside of the XSLT by setting the desired parameters to "true()".-->	<xsl:param name="disablePaginationNavigationControls" />	<xsl:param name="disablePaginationNavigationPrevious" />	<xsl:param name="disablePaginationNavigationControl" />	<xsl:param name="disablePaginationNavigationNext" />		<!--With theese, you can easily manipulate the URLs without many difficulties-->	<xsl:param name="localLinkBefore" select="'?n='"/>	<xsl:param name="localLinkAfter" />	<!--Include a page wrapper. Optional if the rest of the page is not in this XSLT.-->	<xsl:template match="/">		<html>			<head>				<style type="text/css">				.paginationNavigation, .paginationNavigation ul {text-align: center; margin: 0 auto; padding: 0;}				.paginationNavigation ul,  .paginationNavigation ul li {display: inline;}				.paginationNavigation span, .paginationNavigation a {padding: 10px;}				</style>			</head>			<body>				<xsl:apply-templates />			</body>		</html>	</xsl:template>	<!--This is the first "inside" template that gets executed. It's the place for major interface changes and wrappings.-->	<xsl:template match="/*">		<xsl:choose>			<!--Change this path to match the place where your content truly is. Change the one at the for-each as well.-->			<xsl:when test="*[name()=$pagedElement]">				<dl>					<xsl:variable name="startPoint" select="($pageNumber - 1) * $recordsPerPage" />					<xsl:for-each select="*[name()=$pagedElement and position()>=1+ $startPoint and position()<=$startPoint + $recordsPerPage]">						<xsl:call-template name="pagedElement" />					</xsl:for-each>				</dl>				<xsl:if test="$disablePaginationNavigationControls = false()">					<xsl:call-template name="paginationNavigation"/>				</xsl:if>			</xsl:when>			<!--Alternative action(s) for when there are no appropriate items in the XML.-->			<xsl:otherwise>			<h1>No items to be paged.</h1>			</xsl:otherwise>		</xsl:choose>	</xsl:template>	<!-- Specifyes what to do for each paged element. Be sure to change that. -->	<xsl:template name="pagedElement">		<dt><a href="{link}"><xsl:value-of select="title" /></a></dt>		<dd><xsl:value-of select="description" /></dd>		<dd>Category: <xsl:value-of select="category" /></dd>		<dd>Number: <xsl:value-of select="position()" /></dd>	</xsl:template>		<!--This is the place for changing the paginationNavigation's wrapper and to reorder the controls.-->	<xsl:template name="paginationNavigation">		<div class="paginationNavigation">			<xsl:call-template name="previous" />			<xsl:call-template name="paginationNavigationControl" />			<xsl:call-template name="next" />		</div>	</xsl:template>		<xsl:template name="previous">		<xsl:if test="$disablePaginationNavigationPrevious = false()">			<xsl:if test="$pageNumber > 1">				<a href="{$localLinkBefore}{$pageNumber - 1}{$localLinkAfter}">Previous</a>			</xsl:if>		</xsl:if>	</xsl:template>		<xsl:template name="paginationNavigationControl">		<xsl:if test="$disablePaginationNavigationControl = false()">			<ul>				<xsl:for-each select="*[name()=$pagedElement and position() <= $totalPages]">					<xsl:variable name="pageNumberControl" select="count(preceding-sibling::*)+1" />					<li>						<xsl:choose>							<xsl:when test="not($pageNumberControl = $pageNumber)">								<a href="{$localLinkBefore}{$pageNumberControl}{$localLinkAfter}">									<xsl:value-of select="$pageNumberControl" />								</a>							</xsl:when>							<xsl:otherwise>								<span>									<xsl:value-of select="$pageNumberControl" />								</span>							</xsl:otherwise>						</xsl:choose>					</li>				</xsl:for-each>			</ul>		</xsl:if>	</xsl:template>	<xsl:template name="next">	<xsl:if test="$disablePaginationNavigationNext = false()">		<xsl:if test="$pageNumber < $totalPages">			 <a href="{$localLinkBefore}{$pageNumber + 1}{$localLinkAfter}">Next</a>		</xsl:if>	</xsl:if>	</xsl:template></xsl:stylesheet>

Some of the changes I made are:

  • A major change in the formula for selecting the proper page elements. With yours, some items were missing, and the recordsPerPage varied when set to number different then 5.
  • The totalPages parameter now has a ceiling() for cases when there's a need for an extra non-complete page. I admit you had that anticipated from the start and I was the one to remove it but we are talking about generalization here after all.
  • The different navigation controls can be turned off by setting the appropriate parameters to true(). Scince it's a parameter editing, they can be turned off on different events outside the XSLT, such as the existance of a get variable.
  • Some template and parameter renaming that imply only role now. For example "footer" is now "paginationNavigation" scince the navigation is not always going to be a footer.
  • The parameters "localLinkBefore" and "localLinkAfter" make it extremely easy to edit the URL of all links without actually going all deep into the XSLT.
  • Specifying the pagedElement parameter is enough to estabilish the path if the paged element is located below the root. Removing it can be done without any complications, as long as you remove it's every occurance of course.
  • I've added your lastly requested feature of an alternative action when there are no appropriate items in the XML. I tested it, so I'm sure it will work.
  • Possibly other minor changes to accomodate the big ones

And the PHP5 (libxslt) script has only one minor change. I've added the xmlFile and xsltFile variables that hold the file names and nothing more. Here it is:

<?php//Prepare the variables.//This is especially usefull if you only want to rename their name in the URL while keeping their functionality$pageNumber = $_GET['n'];$xsltFile = "test.xsl";$xmlFile = "test.xml";//Prepare the XML file$xml = new DomDocument;$xml->load($xmlFile);//Prepare the XSLT file$xsl = new DomDocument;$xsl->load($xsltFile);//Load the XSLT processor$xslt = new Xsltprocessor;$xslt->importStylesheet($xsl);//Prepare parameter changesif (ereg("^[1-9]*[0-9]", $pageNumber)) //Ensure the $pageNumber is really a number{$xslt->setParameter(NULL, 'pageNumber', $pageNumber);}//Execute the transformation$transformation = $xslt->transformToXml($xml);//Show the transformation in the browser. Just before this phase is the right time to check the output if needed.echo $transformation;?>

Try to rebuild your catalogue by using this code as a base, and please, combine your <style> elements into one.

Share this post


Link to post
Share on other sites

Oh, and thanks to kvnmck18, I'm also able to present the PHP4 (Salbotron) solution.

<?php//Prepare the variables.//This is especially usefull if you only want to rename their name in the URL while keeping their functionality.$pageNumber =  $_GET['n'];$xsltFile = "test.xsl";$xmlFile = "test.xml";//Prepare parameter changesif (ereg("^[1-9]*[0-9]", $pageNumber)) //Ensure the $pageNumber is really a number{$args = array("pageNumber" => $pageNumber);}//Load the XSLT processor$engine = xslt_create();//Execute the transformation$output = xslt_process($engine, $xmlFile, $xsltFile, NULL, NULL, $args);//Show the transformation in the browser. Just before this phase is the right time to check the output if needed.print $output;xslt_free($engine);?>

And I'm still waiting for ASP and JavaScript solutions :) .

Share this post


Link to post
Share on other sites
Oh, and thanks to kvnmck18, I'm also able to present the PHP4 (Salbotron) solution.
<?php//Prepare the variables.//This is especially usefull if you only want to rename their name in the URL while keeping their functionality.$pageNumber =  $_GET['n'];$xsltFile = "test.xsl";$xmlFile = "test.xml";//Prepare parameter changesif (ereg("^[1-9]*[0-9]", $pageNumber)) //Ensure the $pageNumber is really a number{$args = array("pageNumber" => $pageNumber);}//Load the XSLT processor$engine = xslt_create();//Execute the transformation$output = xslt_process($engine, $xmlFile, $xsltFile, NULL, NULL, $args);//Show the transformation in the browser. Just before this phase is the right time to check the output if needed.print $output;xslt_free($engine);?>

And I'm still waiting for ASP and JavaScript solutions :) .

Asp solution:
<%' prevent page cachingResponse.CacheControl = "no-cache"Response.AddHeader "Pragma", "no-cache"Response.Expires = -1 number			= Request.QueryString("n")if number = "" thennumber = "1"end ifxslpath		= Server.mappath("test.xsl")sourceFile 		= Server.mappath("test.xml")  Set source = Server.CreateObject("Msxml2.DOMDocument")  source.async = false  source.load(sourceFile)set xsldoc		= Server.CreateObject("MSXML2.FreeThreadedDOMDocument")xsldoc.async = falsexsldoc.load(xslpath) set xsltemp = Server.createObject("MSXML2.XSLTemplate")xsltemp.stylesheet=xsldocset xslproc = xsltemp.createProcessorxslproc.input=sourcexslproc.output=Response' parameter for message groupxslproc.addParameter "pagenumber",numberxslproc.transformResponse.end%>

:)

Share this post


Link to post
Share on other sites

Now if you can only do a JavaScript way to use this, I can safely call you "JavaScript god" with no doubt :) .This time, I won't forget to give you the cross browser JavaScript code to execute XSLT transofmration inside HTML. The problem is to somehow pass the parameter (not necessary in the URL) that indicates the pageNumber and the such.

Share this post


Link to post
Share on other sites
Now if you can only do a JavaScript way to use this, I can safely call you "JavaScript god" with no doubt :) .This time, I won't forget to give you the cross browser JavaScript code to execute XSLT transofmration inside HTML. The problem is to somehow pass the parameter (not necessary in the URL) that indicates the pageNumber and the such.
In javascript solution:<script language="javascript" src="page.js" /> page.js
function changePage(number){	try{		var s = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");		var x = document.XMLDocument;		if (x == null){			x = navigator.XMLDocument;			s.loadXML(navigator.XSLDocument.xml);		}else{			s.loadXML(document.XSLDocument.xml);		}		var tem = new ActiveXObject("MSXML2.XSLTemplate");		tem.stylesheet = s;		var proc = tem.createProcessor();		proc.addParameter("pagenumber", number);		proc.input = x;		proc.transform();		var str = proc.output;		var newDoc = document.open("text/html", "replace");		newDoc.write(str);		navigator.XMLDocument = x;		navigator.XSLDocument = s;		newDoc.close();	}catch(exception){	}}

and the xsl

- <xsl:template name="footerPages">  <xsl:param name="element" />   <xsl:param name="pagenumber" />   <xsl:variable name="total" select="count(*[name() = $element])" /> - <center>- <xsl:if test="$pagenumber > 1">  <a href="java script:changePage({$pagenumber -1});">Prev</a>   </xsl:if>- <xsl:for-each select="*[name() = $element]">- <xsl:choose>- <xsl:when test="not(count(preceding-sibling::*)+1 = $pagenumber)">    - <a href="java script:changePage({count(preceding-sibling::*)+1});">  <xsl:value-of select="count(preceding-sibling::*)+1" />   </a>  </xsl:when>- <xsl:otherwise>      <xsl:value-of select="count(preceding-sibling::*)+1" />   </xsl:otherwise>  </xsl:choose>  </xsl:for-each>- <xsl:if test="$pagenumber < $total">      <a href="java script:changePage({$pagenumber +1});">Next</a>   </xsl:if>  </center>  </xsl:template>

is ok :) Andrea

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...