UDF: xslt() for CFMX

Posted by Dan on Mar 26, 2003 @ 4:39 PM

I wrote this CFMX-based UDF a while ago, and I thought I'd share it. One of my big gripes about the xslTransform() function in CFMX is that it doesn't support passing parameters to the transformation engine.

Passing parameters can be extremely useful, as it'll allow you to do some conditional operations on in your XSL sheets based upon values determined by the ColdFusion.

In a nutshell, this UDF accomplish this by parsing the XSL stylesheet and looking for instances of the <xsl:param> tag name attributes that match the key in the structure you passed in. Once it's looped through the entire "Params" structure, it'll use the modified XSL stylesheet to do the transformation. Basically, it just temporarily hard codes those values in the param for you.

I've been using the tag for a while and use it in a number of places on my site, but you must take the code as-is. I make no gaurantees it'll work for you!

<cfparam name="attributes.value" type="string" />

<!---// check to see if we were called from within the loop //--->
<cfif listFindNoCase(getBaseTagList(), "cf_loop") gt 0>
    <!---//
        if inside the loop tag, we need to associate ourselves w/the loop tag.
        this will let the loop tag have access to our variables
    //--->

    <cfassociate baseTag="cf_loop">
    <!---// this is a reference to the parent loop tag //--->
    <cfset oParent = getBaseTagData("cf_loop")>

    <!---// output the value of the current loop and the value of the tag //--->
    I am <cfoutput>#oParent.iLoopCounter#</cfoutput> <cfoutput>#attributes.value#</cfoutput>
    <br />

<!---/lt param statements into an array
        oXslParam = xmlSearch(xXsl, "/xsl:stylesheet/xsl:param");
        for( i=1; i lte arrayLen(oXslParam); i=i+1 ){
            // if the current param name is in the passed in struct, then alter
            // the default value according to the passed in value
            if( structKeyExists(stParams, oXslParam[i].xmlAttributes.name) ){
                // remove existing "select" arguments
                structDelete(oXslParam[i].xmlAttributes, "select", true);
                // delete existing children elements
                arrayClear(oXslParam[i].xmlChildren);

                // if the value is numeric, insert it as a numeric value
                if( val(stParams[oXslParam[i].xmlAttributes.name]) eq stParams[oXslParam[i].xmlAttributes.name] ){
                    structInsert(oXslParam[i].xmlAttributes, "select", stParams[oXslParam[i].xmlAttributes.name], true);
                // otherwise, treat value as string
                } else {
                    j = arrayLen(oXslParam[i].xmlChildren)+1;
                    oXslParam[i].xmlChildren[j] = xmlElemNew(xXsl, "xsl:text");
                    oXslParam[i].xmlChildren[j].xmlText = toString(stParams[oXslParam[i].xmlAttributes.name]);
                }
            }
        }

        // transform document based on updated XSL document
        return xmlTransform(sXml, toString(xXsl));
    } else {
        // transform as normal
        return xmlTransform(sXml, sXsl);
    }
    </cfscript>
</cffunction>
Categories: HTML/ColdFusion, Source Code

Comments for this entry have been disabled.