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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XML Paging

Status
Not open for further replies.

eurichunt

Programmer
Nov 14, 2005
11
GB
Hi, I'm pretty new to using xml with asp, although I understand the basics. I need to connect to a feed that holds data on concert tickets that are on sale and use it on our own site.

I can pull all of the xml and format it OK with xsl but because there is so much data the page takes a while loading and would overall be better if I could page through the data maybe 20 records at a time. I've been looking for days to find a decent example of doing this with classic ASP but nothing has turned up that answers all my problems.

My page is coded like this:

<%
dim objHTTP , objXML , objXSL
set objHTTP = Server.CreateObject("Microsoft.XMLHTTP")
objHTTP.open "GET", " false
objHTTP.send
set objXML = objHTTP.responseXML
set objXSL=Server.CreateObject("microsoft.xmldom")
objXSL.async=false

objXSL.load(Server.MapPath("style.xsl"))

if (objXSL.parseError.errorCode = 0) then
Response.Write(objXML.transformnode(objXSL))
else
Response.Write "Error: " & objXSL.parseError.reason & "<br> URL:" & objXSL.url
end if

Set objHTTP = Nothing
Set objXML = Nothing
Set objXSL = Nothing
%>

And my xsl is this:

<xsl:stylesheet xmlns:xsl=" <xsl:template match="/">
<HTML>
<HEAD>
<TITLE>Ticketmaster</TITLE>
</HEAD>
<BODY BGCOLOR="ffffff">
<DIV ALIGN="center">
<TABLE BGCOLOR="ffffff" BORDER="0" CELLPADDING="4" CELLSPACING="0" WIDTH="100%">

<xsl:for-each select="eventList/event">
<TR VALIGN="middle">
<TD ALIGN="left" BGCOLOR="ffffff">
<B><A>
<xsl:attribute name="HREF">
<xsl:value-of select="@uri"/>
</xsl:attribute>
<xsl:attribute name="TARGET">_blank</xsl:attribute>
<FONT FACE="Verdana, Arial,Helvetica, sans-serif" SIZE="-1" COLOR="000000">
<xsl:value-of select="primaryAct"/></FONT>
</A></B>
<BR/>
<FONT FACE="Verdana, Arial,Helvetica, sans-serif" SIZE="-2" COLOR="666666">
<xsl:value-of select="venue"/>
</FONT>
<BR/>
<FONT FACE="Verdana, Arial,Helvetica, sans-serif" SIZE="-2" COLOR="666666">
<xsl:for-each select="primaryAct">
<xsl:value-of select="@date"/>
</xsl:for-each>
<xsl:for-each select="venue">
, <xsl:value-of select="@city"/>
</xsl:for-each>
</FONT>
</TD>
</TR>

</xsl:for-each>


</TABLE>
</DIV>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>

Any help would be greatly appreciated.
 
I don't think its possible to part download an XML file, if it is it will be complicated. Instead of downloading the file for every request, why don't you write another program to periodically download the data to a file on your server. Then you can do the paging in the XSL:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:param name="pos"/>
  <xsl:param name="pageCount"/>
  <xsl:template match="/">
    <HTML>
      <HEAD>
        <TITLE>Ticketmaster</TITLE>
      </HEAD>
      <BODY BGCOLOR="ffffff">
        <DIV ALIGN="center">
          <TABLE BGCOLOR="ffffff" BORDER="0" CELLPADDING="4" CELLSPACING="0" WIDTH="100%">
            <xsl:for-each select="eventList/event[position() &gt; $pos and position() &lt; $pos + $pageCount">
              <TR VALIGN="middle">
                <TD ALIGN="left" BGCOLOR="ffffff">
                  <B>
                    <A>
                      <xsl:attribute name="HREF"><xsl:value-of select="@uri"/></xsl:attribute>
                      <xsl:attribute name="TARGET">_blank</xsl:attribute>
                      <FONT FACE="Verdana, Arial,Helvetica, sans-serif" SIZE="-1" COLOR="000000">
                        <xsl:value-of select="primaryAct"/>
                      </FONT>
                    </A>
                  </B>
                  <BR/>
                  <FONT FACE="Verdana, Arial,Helvetica, sans-serif" SIZE="-2" COLOR="666666">
                    <xsl:value-of select="venue"/>
                  </FONT>
                  <BR/>
                  <FONT FACE="Verdana, Arial,Helvetica, sans-serif" SIZE="-2" COLOR="666666">
                    <xsl:value-of select="primaryAct/@date"/>, <xsl:value-of select="venue/@city"/>
                  </FONT>
                </TD>
              </TR>
            </xsl:for-each>
          </TABLE>
        </DIV>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

Jon

"I don't regret this, but I both rue and lament it.
 
Thanks for the reply, I need to know how to page with xsl, I can't find a decent example anywhere.
 
Use xsl above and this code (not tested):
Code:
<%
dim objHTTP , objXML , objXSL

set objHTTP = Server.CreateObject("Microsoft.XMLHTTP")
objHTTP.open "GET", "[URL unfurl="true"]http://www2.ticketmaster.co.uk/affiliate/gigwise/TMUK_Music_Event_Data.xml",[/URL] false
objHTTP.send
set objXML = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
objXML.loadXML(objHTTP.responseXML)
set objXSL = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
objXSL.async = false

objXSL.load(Server.MapPath("style.xsl"))

if (objXSL.parseError.errorCode = 0) then
  Set oTemplate = Server.CreateObject("MSXML2.XSLTemplate")
  Set oResult = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
  oTemplate.stylesheet = objXSL
  Set oProc = oTemplate.createProcessor()
  oProc.input = objXML
  oProc.output = oResult
  oProc.addParameter "pos", "0"
  oProc.addParameter "pageCount", "20"
  oProc.transform
  Response.Write oResult.xml
else
  Response.Write "Error: " & objXSL.parseError.reason & "<br> URL:" & objXSL.url
end if

Set objHTTP = Nothing
Set objXML = Nothing
Set objXSL = Nothing
%>

Jon

"I don't regret this, but I both rue and lament it.
 
Thanks for that Jon, although I'm now getting:

Type mismatch: 'loadXML'

Also is there an angled bracket missing from this line or one too many?

<xsl:for-each select="eventList/event[position() &gt; $pos and position() &lt; $pos + $pageCount">

 
Try:
Code:
<%
dim objHTTP , objXSL

set objHTTP = Server.CreateObject("Microsoft.XMLHTTP")
objHTTP.open "GET", "[URL unfurl="true"]http://www2.ticketmaster.co.uk/affiliate/gigwise/TMUK_Music_Event_Data.xml",[/URL] false
objHTTP.send
set objXSL = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
objXSL.async = false

objXSL.load(Server.MapPath("style.xsl"))

if (objXSL.parseError.errorCode = 0) then
  Set oTemplate = Server.CreateObject("MSXML2.XSLTemplate")
  Set oResult = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
  oTemplate.stylesheet = objXSL
  Set oProc = oTemplate.createProcessor()
  oProc.input = objHTTP.responseXML
  oProc.output = oResult
  oProc.addParameter "pos", "0"
  oProc.addParameter "pageCount", "20"
  oProc.transform
  Response.Write oResult.xml
else
  Response.Write "Error: " & objXSL.parseError.reason & "<br> URL:" & objXSL.url
end if

Set objHTTP = Nothing
Set objXSL = Nothing
%>
And:
Code:
<xsl:for-each select="eventList/event[position() &gt; $pos and position() &lt; ($pos + $pageCount)]">

Jon

"I don't regret this, but I both rue and lament it.
 
Hmm, just a blank page now. What if I do save the xml as a file on my server will that make a difference?
 
I have tested this code:
Code:
<%
Dim xsldoc
Dim myTemplate
Dim myProc
Dim xmldoc

'It has to be Free-Threaded, the idea is to make the widget available
'to an app and have multple users bang on it.
Set xsldoc = Server.CreateObject("Msxml2.FreeThreadedDOMDocument.3.0")
xsldoc.async = false
xsldoc.load Server.MapPath("style.xsl")

'This is the critical widget, a compliled XSL template
Set myTemplate = Server.CreateObject("Msxml2.XSLTemplate.3.0")
myTemplate.stylesheet = xsldoc

set objHTTP = Server.CreateObject("Microsoft.XMLHTTP")
objHTTP.open "GET", "[URL unfurl="true"]http://www2.ticketmaster.co.uk/affiliate/gigwise/TMUK_Music_Event_Data.xml",[/URL] false
objHTTP.send

Set myProc = myTemplate.createProcessor()
myProc.input = objHTTP.responseXML

'Now set the parameter
myProc.addParameter "pos", "0"
myProc.addParameter "pageCount", "20"
myProc.output = Response
myProc.transform()

%>

Jon

"I don't regret this, but I both rue and lament it.
 
Thanks for that I now have 20 records, I'm now trying to figure out how to page through them using the pos paramater. I need to know how I can count the total number of pages too.
 
You could add some google style paging like this (I've cleaned up your html too, don't use depreciated tags):

XSL (you'll need to change scriptName to your page):
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:param name="page"/>
  <xsl:param name="pageCount"/>
  <xsl:variable name="totalPages" select="ceiling(count(eventList/event) div $pageCount)"/>
  <xsl:variable name="scriptName" select="test.asp"/>
  <xsl:template match="/">
    <html>
      <head>
        <title>Ticketmaster</title>
        <style type="text/css">
body {
  font-family: Verdana, Arial,Helvetica, sans-serif;
  font-size: xx-small;
  color: #666666;
}
div {
  margin-bottom: 1em;
}
a.primaryAct {
  font-size: x-small;
  font-weight: bold;
  color: #000000;
}
div.paging a {
  margin: 3px;
}
        </style>
      </head>
      <body>
        <div class="paging">
          <xsl:if test="$page &gt; 1">
            <a style="text-decoration: none" href="{$scriptName}?page={$page - 1}">&lt; Previous</a>
          </xsl:if>
          <xsl:call-template name="paging">
            <xsl:with-param name="startPage">
              <xsl:choose>
                <xsl:when test="$page &lt; 5">1</xsl:when>
                <xsl:when test="($totalPages - $page) &lt; 5">
                  <xsl:choose>
                    <xsl:when test="($totalPages - 8) &lt; 1">1</xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="($totalPages - 8)"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="$page - 4"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
          </xsl:call-template>
          <xsl:if test="$page &lt; $totalPages">
            <a style="text-decoration: none" href="{$scriptName}?page={$page + 1}">Next &gt;</a>
          </xsl:if>
        </div>
        <xsl:apply-templates select="eventList/event[position() &gt; (($page - 1) * $pageCount) and position() &lt; ($page * $pageCount)]"/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="event">
    <div>
      <a class="primaryAct" href="@uri" target="_blank">
        <xsl:value-of select="primaryAct"/>
      </a>
      <br/>
      <xsl:value-of select="venue"/>
      <br/>
      <br/>
      <xsl:value-of select="primaryAct/@date"/>, <xsl:value-of select="venue/@city"/>
    </div>
  </xsl:template>
  <xsl:template name="paging">
    <xsl:param name="startPage"/>
    <xsl:call-template name="paging2">
      <xsl:with-param name="pageNo" select="$startPage"/>
      <xsl:with-param name="endPage" select="$startPage + 8"/>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="paging2">
    <xsl:param name="pageNo"/>
    <xsl:param name="endPage"/>
    <xsl:if test="not($pageNo = ($endPage + 1) or $pageNo = ($totalPages + 1))">
      <a href="{$scriptName}?page={$pageNo}">
        <xsl:value-of select="$pageNo"/>
      </a>
      <xsl:call-template name="paging2">
        <xsl:with-param name="pageNo" select="$pageNo + 1"/>
        <xsl:with-param name="endPage" select="$endPage"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>
ASP:
Code:
<%
Dim xsldoc
Dim myTemplate
Dim myProc
Dim xmldoc
Dim page
Dim objHTTP

'It has to be Free-Threaded, the idea is to make the widget available
'to an app and have multple users bang on it.
Set xsldoc = Server.CreateObject("Msxml2.FreeThreadedDOMDocument.3.0")
xsldoc.async = false
xsldoc.load Server.MapPath("style.xsl")

'This is the critical widget, a compliled XSL template
Set myTemplate = Server.CreateObject("Msxml2.XSLTemplate.3.0")
myTemplate.stylesheet = xsldoc

set objHTTP = Server.CreateObject("Microsoft.XMLHTTP")
objHTTP.open "GET", "[URL unfurl="true"]http://www2.ticketmaster.co.uk/affiliate/gigwise/TMUK_Music_Event_Data.xml",[/URL] false
objHTTP.send

Set myProc = myTemplate.createProcessor()
myProc.input = objHTTP.responseXML

page = "1"
if Request.QueryString("page") <> "" then
  page = Request.QueryString("page")
end if

'Now set the parameter
myProc.addParameter "page", page
myProc.addParameter "pageCount", "20"
myProc.output = Response
myProc.transform()

%>

Jon

"I don't regret this, but I both rue and lament it.
 
I get:

The stylesheet does not contain a document element. The stylesheet may be empty, or it may not be a well-formed XML document.
 
You've saved the XSL as style.xsl, and its in the same folder as the asp page?

Jon

"I don't regret this, but I both rue and lament it.
 
Make sure you've copied the code from my last page properly. If you've changed anything, post the changes. I've just tested it again and it works.

Jon

"I don't regret this, but I both rue and lament it.
 
For some reason, this line is not looking in the right place for your xsl file:
Code:
xsldoc.load Server.MapPath("style.xsl")
Try:
Code:
xsldoc.load "style.xsl"
If that doesn't work try finding out what directory your in by using:
Code:
Response.Write Server.MapPath(".")
I've uploaded it to one of my sites:


Jon

"I don't regret this, but I both rue and lament it.
 
OK it's just not having it on our server. Is there any chance that I've got something up with the server if your code is bang on?
 
I don't know much about servers. Maybe check what version of MSXSL its using?

Jon

"I don't regret this, but I both rue and lament it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top