Link to home
Start Free TrialLog in
Avatar of eaweb
eawebFlag for undefined

asked on

xsl pagination

hi,
i have xml data which is structured like:
<ERRReport>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
</ERRReport>

I am using below xslt to display the data formatted and when printing i use page break. Now i need paginate the data using some kind of xslt pagination code. As you can see every <ERRReportPage>xml data</ERRReportPage> is a page and need to toggle through using a paging system. Please some code help that is suitable for both IE and firefox


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link href="images/eibERRReport.css" rel="stylesheet" type="text/css" />
<link href="images/printERRReport.css" rel="stylesheet" type="text/css" media="print" />
</head>
<body>    
<xsl:apply-templates/>    
</body>
</html>
</xsl:template>
<xsl:template match="ERRReport">
<xsl:for-each select=".">        
      <table width="670"  border="0" cellpadding="0" cellspacing="0" align="center" class="pageof">
            <tr>
                  <td align="right"><form><input type="button" value="Print Report" onclick="window.print();return false;" class="buttonLong" /></form>
                  </td>
            </tr>
      </table>
     
      <xsl:for-each select="ERRReportPage">              
            <br />  
            <table width="670" height="600" cellpadding="0" cellspacing="0" class="borderthin" align="center">
                  <tr>
                        <td>
                              DATA                              
                        </td>
                  </tr>
            </table>
            <xsl:if test="position()!=last()">
      <DIV style="page-break-before: always"></DIV>
    </xsl:if>        
      </xsl:for-each>
               
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

pagination browser side means JavaScript
so you need a cross-browser XML library.
I can recommend that you download Sarissa from sourceforge
(google for download sarissa, that will help)

than you perform your XSLT, and you pass a parameter, for the pagenumber
I will make an example in a minute, it is not too hard
This would be the html driver file,
each call to the showPage function triggers the div 's innerhtml to be overwritten
in the function a xslt process is called, passing the pagenumber to the XSLT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
	  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
		<script type="text/javascript" src="script/sarissa.js"></script>
		<script type="text/javascript" src="script/sarissa_ieemu_xpath.js"></script>
		<script type="text/javascript" language="JavaScript">
		  <!--
		  // create the xml document object
		  var oXML = Sarissa.getDomDocument();
		  oXML.async = false;
		  oXML.load("page.xml");
		  //alert(new XMLSerializer().serializeToString(oXML));
		  
		  // create an object from the xsl
		  var oXSL = Sarissa.getDomDocument();
		  oXSL.async = false; 
		  oXSL.load("page.xsl");
		  //alert(new XMLSerializer().serializeToString(oXSL));
		  
		  function showPage(no)
		    {
		      var xsltProc  = new XSLTProcessor();
		      xsltProc.importStylesheet(oXSL);
		      xsltProc.setParameter('', "page-number", no);
		      var treeResult = xsltProc.transformToDocument(oXML);
		      //alert(new XMLSerializer().serializeToString(treeResult));
		      document.getElementById("PAGE").innerHTML = new XMLSerializer().serializeToString(treeResult);
		    }
	
		  // -->
	    </script>
	</head>
	<body onload="showPage('1');">
		  <div id="PAGE"></div>
	</body>
</html>

Open in new window

you need to download sarissa and put the two relevant files in the script directory, xml and xslt come next to the html driver file
Here is the XSLT you would need, very straightforward
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="page-number">3</xsl:param>
    <xsl:param name="total-pages" select="count(//ERRReportPage)"/>
    <xsl:param name="previous">
        <xsl:choose>
            <xsl:when test="$page-number > 1">
                <xsl:value-of select="$page-number - 1"/>
            </xsl:when>
            <xsl:otherwise>1</xsl:otherwise>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="next">
        <xsl:choose>
            <xsl:when test="$page-number &lt; $total-pages">
                <xsl:value-of select="$page-number + 1"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$total-pages"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>
 
    <xsl:template match="/">
        <div>
            <button id="previous" type="button" >
                <xsl:attribute name="onClick">
                    <xsl:text>showPage('</xsl:text>
                    <xsl:value-of select="$previous"/>
                    <xsl:text>'); </xsl:text>
                </xsl:attribute>
                <xsl:text>--PREVIOUS--</xsl:text>
            </button>
            <button id="next" type="button" >
                <xsl:attribute name="onClick">
                    <xsl:text>showPage('</xsl:text>
                    <xsl:value-of select="$next"/>
                    <xsl:text>'); </xsl:text>
                </xsl:attribute>
                <xsl:text>--NEXT--</xsl:text>
            </button>
            <br />
            <xsl:apply-templates select="ERRReport"></xsl:apply-templates>
        </div>
    </xsl:template>
 
    <xsl:template match="ERRReport">
        <xsl:apply-templates select="ERRReportPage[position() = $page-number]"/>
    </xsl:template>
    
    <xsl:template match="ERRReportPage">
        <h1><xsl:value-of select="."/></h1>
    </xsl:template>
</xsl:stylesheet>

Open in new window

Avatar of eaweb

ASKER

it looks easy but how must i implement it to my code. i already downloaded the sarissa files. i dont understand how to apply the two code sample you supplied to my xslt.
How were you applying them before?
You asked for IE and FireFox, so I assume you want a browser based solution.
Likely, before you were sending the XML to the browser, with an xsm-stylesheet procesisng instructyion, to trigger the XSLT.
You can't do that anymore for paging
You now send the HTML with embedded javascript to the browser and make sure the browser find the sarissa and xslt and xml files as indicated, you will see that the html + javascript will render your xml, transformed in one page of html

put the xml as page.xml and the xsl as page.xsl in the same directory as  the html driver file (call that one page.html)
now put the two before mentioned sarissa files in a script subdirectory
now open the page.html file with a browser and you will see the results

Inside the template for
    <xsl:template match="ERRReportPage">
        <h1><xsl:value-of select="."/></h1>
    </xsl:template>
you can put the processing you were doing before with ERRReportPage
you will likely end up with something like this
   <xsl:template match="ERRReportPage">
          <table width="670" height="600" cellpadding="0" cellspacing="0" class="borderthin" align="center">
                  <tr>
                        <td>
                              <xsl:value-of select="."/>
                        </td>
                  </tr>
            </table>
    </xsl:template>

Open in new window

Avatar of eaweb

ASKER

i get the xml from a database. how must i supply it (page.xml) in the html driver file
how did you apply the XSLT before?
Avatar of eaweb

ASKER

in a asp page i do the following request:

dim xmlhttp
set xmlhttp = server.Createobject("MSXML2.ServerXMLHTTP")
xmlhttp.Open "POST",getValForErrDatUrl,false
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send Geterrrepview
Response.ContentType = "text/xml"
Response.Write xmlhttp.responsexml.xml
Set xmlhttp = nothing

and as response i get the xml and xslt attached to it like

<?xml version="1.0"?>
<?xml-stylesheet type='text/xsl' href='StylesheetXML.xsl'?>
<ERRReport>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
</ERRReport>

and the browser rendered it

Oh well, you are serving this up using ASP?

The logic would be similar...
but why do you do the XSLT client side,
if you do the XSLT server side, you can simply do all the logic on your server in ASP and serve HTML up
you would then not need sarissa, but simply VBScript XSLT
Avatar of eaweb

ASKER

yes i am using asp. how must the VBScript XSLT look like. i am a newbie in xslt paging
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of eaweb

ASKER

sorry i am confused here with

# make sure that you make your XML object here,
# the way you did before ...

do you mean like this:

dim xmlhttp
set xmlhttp = server.Createobject("MSXML2.ServerXMLHTTP")
xmlhttp.Open "POST",getValForErrDatUrl,false
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send Geterrrepview
Response.ContentType = "text/html"
Response.Write xmlhttp.responsexml.xml
Set xmlhttp = nothing

but here the data come as xml format
<ERRReport>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
      <ERRReportPage>xml data</ERRReportPage>
</ERRReport>
Avatar of eaweb

ASKER

or can i do it like this

<%
Dim oXML
Set oXML = Server.CreateObject("MSXML2.DOMDocument.4.0")
Dim oXSL
Set oXSL= Server.CreateObject("Msxml2.FreeThreadedDOMDocument.4.0")
Dim oTmpl
Set oTmpl= Server.CreateObject("Msxml2.XSLTemplate.4.0")
Dim oProc
 
oXSL.async = false
oXSL.load Server.MapPath("page.xsl")
 
dim xmlhttp
set xmlhttp = server.Createobject("MSXML2.ServerXMLHTTP")
xmlhttp.Open "POST",getValForErrDatUrl,false
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send Geterrrepview

oXML.load xmlhttp.responsexml.xml

oTmpl.stylesheet = oXSL
 
Set oProc= oTmpl.createProcessor()
oProc.input = oXML
 
oProc.addParameter "page-number", no # no being an integer containing the page number
oProc.output = Response
oProc.transform()
  Set xmlhttp = nothing
%>
Avatar of eaweb

ASKER

@gertone,

hi, i did what you suggest but it doesn't seem to work when i try to get the xml (xmldata) from the database in objXML.load. with Server.MapPath it is working fine but with objXML.load(xmldata) not. what am i doing wrong?

***code***

xmldata = oRsCurrentStatement.Fields("STMTR_XD").Value

      'Response.Write xmldata
      Dim objXML
      Dim objXSL
      Dim strHTML
      
      'Load the XML File
      Set objXML = Server.CreateObject("Msxml2.FreeThreadedDOMDocument")
      objXML.async = False
      objXML.load(xmldata)
      'objXML.load(Server.MapPath("XSLT/xmlData.xml"))
      
      
      'Load the XSL File
      Set objXSL = Server.CreateObject("Msxml2.FreeThreadedDOMDocument")
      objXSL.async = False
      objXSL.load(Server.MapPath("XSLT/curstatementstylesheet.xsl"))      
      
      Set template = Server.CreateObject("MSXML2.XSLTemplate.3.0")
    Set template.stylesheet = objXSL
    Set proc = template.createProcessor  
    proc.input = objXML

    proc.addParameter "PageNr", submittedpageRequest
      proc.addParameter "PageSize", submittedpageTotal
       
    proc.transform
    Response.Write proc.output
        
      Set objXML = Nothing
      Set objXSL = Nothing
      
      Set oRsCurrentStatement = Nothing
    objXML.load(xmldata)
 ...
load is for loading a serialised XML file from the server path or from a string
I don't know what type of object your xmldata is... it could be that it allready is an xml object,
so you can use it directly, without loading
eg.
     objXML = xmldata
depends on what a beast the xmldata is  
 
Avatar of eaweb

ASKER

i solve it with

objXML.loadXML(xmldata)