Posts Tagged ‘FreeThreadedDOMDocument’

Pulling External Content Into XSL Using ASP

Tuesday, November 4th, 2008

Problem: how to pull content into an XSL transformation process using ASP. ASP will give us the opportunity to make runtime decisions. In my case, determining what sort of template XHTML code to retrieve for inclusion into the final page render.

Let’s say we have an ASP file called ASPResources.asp that retrieves XHTML content from a webserver by passing a filename like such:

Sample ASP:

<%
Class ASPResources

‘ Returns string of HTML content based on filename
Public Function GetHttpContent(fileName)

Dim xml, url, strData
url = “http://localhost/templates/” + fileName + “.asp”
strData = “”

‘ Create an xmlhttp object
Set xml = Server.CreateObject(“Msxml2.ServerXMLHTTP.4.0″)

‘ Open the connection to the remote server.
xml.Open “GET”, url, False

‘ Send the request and returns the data:
xml.Send()

‘ Return content
GetHttpContent = xml.ResponseText

‘ Cleanup
Set xml = Nothing

End Function

End Class
%>

Pretty basic stuff. You’ll want to add error handling and so forth.

Now, to perform the transformation, we have another ASP file called XMLTransformer.asp. This file grabs our XSL and XML files. Then, we create an XSLT (transformation) object from these. The next part is crucial (and bolded below). Instantiate your custom ASP class and add it to the XSL Processor providing a URN, in this case asp-resources.

Sample ASP:

<%
‘ Declare locals
dim xslt
dim xslDoc
dim xslProc
dim xmlDoc

‘ Create XSLT and XSL objects
Set xslt = Server.CreateObject(“Msxml2.XSLTemplate”)
Set xslDoc = Server.CreateObject(“Msxml2.FreeThreadedDOMDocument”)

‘ Load XSL
xslDoc.async = false
xslDoc.resolveExternals = true
xslDoc.load Server.MapPath(pathToXsl)

‘ Set the XSL on the XSLT
Set xslt.stylesheet = xslDoc

‘ Load XML
Set xmlDoc = Server.CreateObject(“Msxml2.DOMDocument”)
xmlDoc.async = false
xmlDoc.resolveExternals = true
xmlDoc.preserveWhiteSpace = true
xmlDoc.load Server.MapPath(pathToXml)

‘ Set the XSLProcessor
Set xslProc = xslt.createProcessor
xslProc.input = xmlDoc

‘ Create our custom object
Set aspr = new ASPResources

‘ Add custom object to XSL template
call xslProc.addObject(aspr, “urn:asp-resources”)

‘ Transform the document
xslProc.transform()

‘ Send the result
Response.Write xslProc.output

‘ Clean up
Set xslt = Nothing
Set xslDoc = Nothing
Set xslProc = Nothing
Set xmlDoc = Nothing
Set aspr = Nothing

%>

At this point, our custom ASP code is now available to the XSL Processor. That’s a happy place to be. But, we’re not quite done yet. We still need to call the custom object from within our XSL. To do so, it is necessary to add the new URN to the list of XMLNS (XML Namespaces) in the XSL file:

<xsl:stylesheet version=”1.0″
xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”
xmlns=”http://www.w3.org/1999/xhtml”
xmlns:aspr=”urn:asp-resources”>

Without this, the XSL transformation will complain about aspr not being a valid namespace. But, with it, we now have access to the custom ASP code and can call its methods elsewhere in our in the XSL code:

<xsl:value-of
select=”aspr:GetHttpContent(‘header’)”
disable-output-escaping=”yes” />

Don’t omit the disable-output-escaping=”yes” parameter. Doing so will cause the parser escape the < and > characters (among others) breaking your XHTML output.

Here we are sending “header” as our filename to the GetHttpContent method resulting in a call to header.asp. This file itself can execute ASP code or simply return XHTML code. The call to GetHttpContent can be done repeatedly in the XSL each time sending a different filename parameter as needed.


All works licensed under Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License. And that's a mouthful!