BizTalk Utilities CV ,   Jobs ,   Code library
 
Home Page


Add/Edit your code items
Search the code library
Browse for the code library


Microsoft ASP
ASP Create Yearly XML Calendar
XML Strengths & Weakness’ with DOM, ASP & XSL
FAQ - My ASP MSXML transformation always outputs UTF-16?
WAP with ASP - starting the WAP adventure
ASP/XML Guest Book
Include an ASP-file in XSL (JITIC Solution)
Read/write data with VB using ASP pages


 
 

<< LAMP 


By Mark Wilson
I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
First Posted 04/10/2001
Times viewed 2086

How to pass values into an XSLT stylesheet from ASP


This post contains attachments
v20010410230220.zip 

Summary A common question is 'how do I pass a value into a XSLT document'. In this example I will show you how we do it on TopXML, explaining the different ways to pass values into the stylesheet.

The easiest way to transform an XSLT file with an XML file is to use the DOM object's transformnode function:

 <%
      set xslDoc = server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0) 
      xsldoc.async = false 
      xslDoc.load server.MapPath(members.xml) 
    
      set xslDoc = server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0) 
      xsldoc.async = false 
 
      xslDoc.load server.MapPath(members.xsl) 
      Response.Write xmldoc.transformnode(xsldoc)
%>

Please note that we always use the FreeThreadedDOM when working with ASP so that the object is stateless and free-threaded, therefore we can store the object as an application variable so that we can share the object.

From the July MSXML parser (version 2.6) the <xsl:param> element in XSLT was implemented.  The <xsl:param> element enables one to pass a value into the stylesheet.

In our example we will be using the following members XML:

<members>
 <member registered=20010125 id=i1001>
  <email>trace_wilson@yahoo.com</email>
  <details f_name=Trace C l_name=Wilson country=AU gender=F dob=19700418/>
 </member>
 <member registered=20010126 id=i1002>
  <email>jbarnes@hotmail.com</email>
  <details f_name=Jenny l_name=Barnes country=US gender=F dob=19720720/>
 </member>
 <member registered=20010202 id=i1003>
  <email>davidk@yahoo.com</email>
  <details f_name=David l_name=Knight country=US gender=M dob=19650701/>
 </member>
 <member registered=20010202 id=i1004>
  <email>mike.todd@wakeup.com</email>
  <details f_name=Mike l_name=Todd country=AU gender=M dob=19701218/>
 </member>
</members>

In this snippet I'll be demonstrating how to pass in
1. a value: so that we can do a search on the value
2. a node-set: where we will iterate through the node-set
3. an XML document: a replacement for using the XSLT document() function

Scenario 1: Passing in a value to the XSLT stylesheet
========================================

In the following XSLT example we want to find Mike Todd's details and pass his id into the stylesheet, to display his details:

<?xml version=1.0  ?>
<xsl:stylesheet version=1.0
                xmlns:xsl=http://www.w3.org/1999/XSL/Transform>

  <xsl:output method=html indent=no />
  <xsl:param name=id />

  <xsl:template match=members>
    <xsl:apply-templates select=member[@id=$id] />
  </xsl:template>
 
  <xsl:template match=member>
    <h1>Member: <xsl:value-of select=concat(details/@f_name, ' ', details/@l_name) /></h1>
    <p>Email: <a href=mailto:{email}><xsl:value-of select=email /></a><br />
    Country: <xsl:value-of select=details/@country />
    </p>
  </xsl:template>
 
</xsl:stylesheet> 

(members.xsl)

From our ASP we want to pass the param called 'id' into the stylesheet.  In the <xsl:apply-templates > we are only wanting to process Mike Todd's details (select=member[@id=$id]).

The ASP for doing this is:

 <%
      dim xslDoc, xmlDoc
      dim id
     
      set xmlDoc=server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0)
      set xslDoc=server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0)
     
      xmldoc.async = false
      xslDoc.async = false
     
      xmlDoc.load server.mapPath(members.xml)
      xslDoc.load server.mapPath(members.xsl)
     
      Set template = Server.CreateObject(MSXML2.XSLTemplate.3.0)
      Set template.stylesheet = xslDoc
      Set proc = template.createProcessor 
      proc.input = xmlDoc 
     
      proc.addParameter id, i1004       
      proc.transform
      Response.Write proc.output
%>

The Template object's main functions is a way to allow us to cache a compiled XSLT stylesheet in an application variable.  To do the transformation of the XML/XSLT we need to create an XSLProcessor, using the createProcessor function of the XSLTemplate object.  The XSLProcessor also allows us to pass parameters into an XSLT document.

In the above ASP code using the XSLProcessor object we pass in a value, but what happens if we want to pass the node of Mike Todd's details instead of doing the search for his details in the stylesheet? 

Scenario 2: Passing in a node-set from the DOM into the XSLT stylesheet
=======================================================

In this example we want to pass in a 'member' node-set to our XSLT from our ASP where the members date of birth is before 1970.  We need to use the selectNodes method of the DOM to return a node-set, which we pass to the stylesheet.

<%
      dim xslDoc, xmlDoc
      dim id
     
      set xmlDoc=server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0)
      set xslDoc=server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0)
     
      xmldoc.async = false
      xslDoc.async = false
     
      xmlDoc.load server.mapPath(members.xml)
      xslDoc.load server.mapPath(member-node.xsl)
     
      Set template = Server.CreateObject(MSXML2.XSLTemplate.3.0)
      Set template.stylesheet = xslDoc
      Set proc = template.createProcessor 
      proc.input = xmlDoc 
     
      set node = xmlDoc.documentElement.selectNodes(member[details/@dob < '19710000'])
      proc.addParameter member, node       
      proc.transform
      Response.Write proc.output
%>

(member-node.asp)

In the stylesheet we are iterating through the members that were found in our selectNodes DOM method.

<?xml version=1.0  ?>
<xsl:stylesheet version=1.0
                xmlns:xsl=http://www.w3.org/1999/XSL/Transform>

  <xsl:output method=html indent=no />
  <xsl:param name=member />

  <xsl:template match=members>
 
    <xsl:for-each select=$member>
      <h1>Member: <xsl:value-of select=concat(details/@f_name, ' ', details/@l_name) /></h1>
      <p>Email: <a href=mailto:{email}><xsl:value-of select=email /></a><br />
      Country: <xsl:value-of select=details/@country />
      </p>
    </xsl:for-each>
  </xsl:template>
 
</xsl:stylesheet>

(member-node.xsl)

Scenario 3: Passing in an XML Document, replacement for the XSLT document() function
==================================================================

On VBXML.COM we store our XML documents as application variables, so that we take advantage of cached data.  This is instead of using the XSLT document() function, which needs to load the XML document each time. 

Passing in the XML document is the same as passing a value into the XSLT stylesheet and it works the same as the document() function, in that you need to work with the document from the root of the document.

From our first example we want to pass in a reference data XML file that has all the countries so that we can display the members full country name.  I would normally use an application variable, but for the sake of this snippet, I'm loading the reference data.

Our refdata.xml looks as follows:
<countries>
  <country code=AF>Afghanistan</country>
  <country code=AL>Albania</country>
  <country code=DZ>Algeria</country>
....

As you can see in the ASP below, we pass in the whole XML document object.
 <%
      dim xslDoc, xmlDoc
      dim id
     
      set xmlDoc=server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0)
      set xslDoc=server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0)
     
      xmldoc.async = false
      xslDoc.async = false
     
      xmlDoc.load server.mapPath(members.xml)
      xslDoc.load server.mapPath(member-doco.xsl)
     
      'load the reference data
      set xmlRefdata=server.CreateObject(Msxml2.FreeThreadedDOMDocument.3.0)
      xmlrefdata.async = false
      xmlRefdata.load server.MapPath(refdata.xml)
     
      Set template = Server.CreateObject(MSXML2.XSLTemplate.3.0)
      Set template.stylesheet = xslDoc
      Set proc = template.createProcessor 
      proc.input = xmlDoc 
     
      proc.addParameter id, i1004       
      proc.addParameter doco-refdata, xmlrefdata
      proc.transform
      Response.Write proc.output
%>
(member-doco.asp)

<?xml version=1.0  ?>
<xsl:stylesheet version=1.0
                xmlns:xsl=http://www.w3.org/1999/XSL/Transform>

  <xsl:output method=html indent=no />
  <xsl:param name=id />
  <xsl:param name=doco-refdata />

  <xsl:template match=members>
    <xsl:apply-templates select=member[@id=$id] />
  </xsl:template>
 
  <xsl:template match=member>
    <h1>Member: <xsl:value-of select=concat(details/@f_name, ' ', details/@l_name) /></h1>
    <p>Email: <a href=mailto:{email}><xsl:value-of select=email /></a><br />
   
    <xsl:variable name=country-code select=details/@country />
    Country: <xsl:value-of select=$doco-refdata/countries/country[@code=$country-code] />
    </p>
  </xsl:template>
 
</xsl:stylesheet>

(member-doco.xsl)

We now reference this document using the following XSLT where we reference the document:
    <xsl:variable name=country-code select=details/@country />
    Country: <xsl:value-of select=$doco-refdata/countries/country[@code=$country-code] />

Additional information


Rate this article on a scale of 1 to 10 (1 votes, average 9)

Your vote :  

<< LAMP 





Leave a comment for this article
Your name
Your email (optional)
Your comment
Optional: Upload an attachment
Enter the code shown:

 
 

    Email TopXML