The following tip was sent to me by Ben Cline, and is posted verbatim. Thanks Ben.
Ben writes …
I found something lacking in the Macromedia documentation and nearly everything I’ve read about CF. It’s the use of XSL parameters. I found a way to successfully do this, and have tried to send something to Macromedia about this, but have never gotten a response back. As you know, using XSL parameters is something that vastly improves the usability of XSL transformations.
All of the code in this tip will use cfscript. If you are unfamiliar with xml, xsl, and xpath, refer to xml documentation.
The key to increasing the productivity of xsl stylesheets comes through xsl:params. Most xml implementations of xml parsers and transformers carry the option of loading up an xsl sheet with parameters.
Before using xsl, it is important that xml be defined as the source document. After the xml has been created, xsl will be made for transforming the xml. Creating an xsl transform to execute the same every time betrays the flexibility that xsl brings to xml. Content output from an xsl transform should instead be dynamic. This can be accomplished by sending variable data into xsl through the use of parameters. During the process of creating an xsl page, the variables for holding dynamic information can be created at the top of an xsl file. The code below shows a parameter within xsl for text color. Notice no value is placed on the xsl:param line, usually indicated by select=””.


To access the part of an xsl sheet that holds the parameters, we will need to parse an xsl file. Since xsl code is actually by definition xml itself, we should not have any problems in doing this within Cold Fusion. We will assume that xsl is already read into a variable xslSrc.
xslParsed = xmlParse(xslSrc);
After Cold Fusion has parsed the xsl file, we will use xpath to get access to the current parameters within the xsl file. If you set a default value, this will verify that the parameter has been passed into Cold fusion. The xmlSearch function creates an array for us of all of the xsl:param nodes. The next snippet assumes a structure of xsl:params values has been passed here, through a udf or cfc, called stcParamLocal. The structure of stcParamLocal would have a key of textColor with a value, perhaps #FF0000 for red.
The snippets loops through the structure of values (stcParamLocal). It first checks to make sure that the xsl:param nodes that are returned are the ones found at the beginnning of the xsl document (in which it’s xml parent must be xsl:stylesheet). Then by looking through the array of xsl:param nodes, it compares the structure keys to stcParamLocal. if one matches, it places the value from stcParamLocal as a new xml attribute node on the xsl:param tag (select=”#FF0000″).

arrParamNode = xmlSearch(xslParsed, "//xsl:param");
for(intParamNLCnt=1; intParamNLCnt lte arrayLen(arrParamNode); intParamNLCnt=intParamNLCnt+1) {
if(arrParamNode[intParamNLCnt].xmlParent.xmlName neq "xsl:template") {
/* do nothing here, these would be xsl:template specific parameters. */
}
else {
/* update XSL-page specific parameters */
strParamXmlName = arrParamNode[intParamNLCnt].xmlAttributes.name;
if(structKeyExists(stcParamLocal,strParamXmlName)) {
strParamVal = "'" & structFind(stcParamLocal,strParamXmlName) & "'";
/* add the xsl:param attribute select with the literal value paramVal. */
structInsert(arrParamNode[intParamNLCnt].xmlAttributes,"select",strParamVal,true);
}
}
}

This example shows that it is possible to access much more about an xsl document than merely the nodes. Parameter values are accessible through searching the xsl document for “xsl:param” nodes. Using the built-in xmlSearch functions, it is also possible to search namespaces and take advantage of the extended inherent capabilities of xml documents.

One thought

  1. Dan Switzer used the same approach for a clever UDF:
    http://www.cflib.org/udf.cfm?ID=899
    Another possibility is use Java, I wrote a bunch of dedicated UDFs this way. One for manipulating XSLT code as string using parameters:
    http://www.cfmentor.com/code/index.cfm?action=script&id=137
    Demo:
    http://www.massimocorner.com/demos/xslTransformString.zip
    This one instead read XSLT directely from files:
    http://www.cfmentor.com/code/index.cfm?action=script&id=136
    Demo:
    http://www.massimocorner.com/demos/xslTransformFile.zip
    The benefit of the second UDF is that by reading XSLT from files it handles include and import inside XSLT templates, something not possible out of the box.
    Both my UDFs are available from the italian CFUG, together with other stuff like UDF for validating XML against a DTD:
    http://www.cfmentor.com/code/index.cfm?action=ls_script&cat=14
    The code is written and commented in english, same for the demo files. Hope they could help
    Massimo

Leave a Reply