View comments | RSS feed

XmlTransform

Description

Applies an Extensible Stylesheet Language Transformation (XSLT) to XML. The XML can be in string format or an XML document object.

Returns

A string containing the results of applying the XSLT to the XML.

Category

Conversion functions, XML functions

Function syntax

XmlTransform(xml, xsl[, parameters])

See also

cfxml, XmlFormat, XmlNew, XmlParse, XmlSearch, XmlValidate; Using XML and WDDX in ColdFusion MX Developer's Guide

History

ColdFusion MX 7: Added the parameters parameter and the ability to use a file for the XSL.

ColdFusion MX: Added this function.

Parameters

Parameter Description

xml

An XML document in string format, or an XML document object

xsl

XSLT transformation to apply; can be any of the following:

Any of the following:

  • A string containing XSL text.
  • The name of an XSTLT file. Relative paths start at the directory containing the current CFML page.
  • The URL of an XSLT file; valid protocol identifiers include http, https, ftp, and file. Relative paths start at the directory containing the current CFML page.

parameters

A structure containing XSL template parameter name-value pairs to use in transforming the document. The XSL transform defined in the xslString parameter uses these parameter values in processing the XML.

Usage

An XSLT converts an XML document to another format or representation by applying an Extensible Stylesheet Language (XSL) stylesheet to it. XSL, including XSLT syntax is specified by the World Wide Web Consortium (W3C). For detailed information on XSL and XSLT, see the W3C website at www.w3.org/Style/XSL/.

If the XSLT code contains include statements with relative paths, ColdFusion resolves them relative to the location of the XSLT file, or for an XSL string, the location of the current ColdFusion page.

Example

The following example converts an XML document that represents a customer order into an HTML document with the customer name and a table with the order items and quantities:

The custorder.xml file that represents a customer order has the following lines:

<?xml version="1.0" encoding="UTF-8"?>
<order id="4323251">
   <customer firstname="Philip" lastname="Cramer" accountNum="21"/>
   <items>
      <item id="43">
         <name>Deluxe Carpenter&apos;s Hammer</name>
         <quantity>1</quantity>
         <unitprice>15.95</unitprice>
      </item>
      <item id="54">
         <name>36&quot; Plastic Rake</name>
         <quantity>2</quantity>
         <unitprice>6.95</unitprice>
      </item>
      <item id="68">
         <name>Standard paint thinner</name>
         <quantity>3</quantity>
         <unitprice>8.95</unitprice>
      </item>
   </items>
</order>

The custorder.xsd XSLT file that transforms the XML to HTML that displays the customer's name, and the items and quantities ordered has the following lines:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.0 Transitional//EN" />
   <xsl:template match="/">
      <html>
         <body>
            <table border="2" bgcolor="yellow">
               <tr>
                  <th>Name</th>
                  <th>Price</th>
               </tr>
               <xsl:for-each select="breakfast_menu/food">
                  <tr>
                     <td>
                        <xsl:value-of select="name"/>
                     </td>
                     <td>
                        <xsl:value-of select="price"/>
                     </td>
                  </tr>
               </xsl:for-each>
            </table>
         </body>
      </html>
   </xsl:template>
</xsl:stylesheet>

The CFML file has the following lines:

<cffile action="read" file="C:\CFusionMX7\wwwroot\examples\custorder.xsl" variable="xmltrans">
<cfset xmldoc = XmlParse("C:\CFusionMX7\wwwroot\examples\custorder.xml")>
<cfoutput>#XmlTransform(xmldoc, xmltrans)#</cfoutput>

ColdFusion 9 | ColdFusion 8 | ColdFusion MX 7 | ColdFusion MX 6.1 | ColdFusion MX | Forums | Developer Center | KnowledgeBase | Bug Reporting

Version 7

Comments


No screen name said on Apr 12, 2005 at 6:22 AM :
einfo, i also tried passing a structure for the parameter option, to no avail. I en ded up using a HashMap instead:

params = createObject("java", "java.util.HashMap").init();
params.put("paramName", paramValue);
xmlTransform(xml, xsl, params);
TimD224 said on Apr 15, 2005 at 11:32 AM :
There seems to be problems with the example code included:

The xsl filename should be custorder.xsl (versus custorder.xsd), and the text of the document does not match the provided custorder.xml file.

After corrections the custorder.xsl file should read:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.0 Transitional//EN" />
<xsl:template match="/">
<html>
<body>
<table border="2" bgcolor="yellow">
<tr>
<th>Name</th>
<th>Price</th>
</tr>
<xsl:for-each select="order/items/item">
<tr>
<td>
<xsl:value-of select="name"/>
</td>
<td>
<xsl:value-of select="unitprice"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
tedmasterweb said on Aug 1, 2005 at 9:05 AM :
I keep forgetting... you can only add structure elements via the StructInsert() function. The JavaScript shorthand (of simply adding the structure name after a dot) is not valid.
www.xmlstandards.org said on Sep 26, 2005 at 8:06 PM :
<!---
Author:
Ethan Cane (ethan@xmlstandards.org)

Description:
ColdFusion MX (Blackstone) provides the ability to transform an XML document
using an XSLT stylesheet using the XmlTransform() function as shown below:

<cfoutput>#XmlTransform(xml, xsl[, parameters])#</cfoutput>

The first two arguments of this function are both required leaving an optional
[parameters] argument, which according to Macromedia ought to be a structure
of named value pairs used by your XSLT stylesheet.

Unfortunately there appears to be some confusion in how structures need to be
constructed in order for this argument to work correctly. It would appear that
your structure needs to use the following two build methods:

1.) Associative array notation: <cfset parameters["param-name"] = "param-value"/>

2.) Function notation: <cfset StructInsert(parameters, "param-name", "param-value")/>

Using the "Object notation" simply does not work even though it does
create a valid structure object; <cfset parameters.param-name = "param-value"/>.

I presume the reason for this might be the potential use (as shown) of the hyphen
character (param-name) which ColdFusion would interpret as a mathematical operation.

Coded below is a brief working example of how to successfully pass parameters to an
XSLT stylesheet via ColdFusion MX (Blackstone).

For the purposes of compactness both the target XML document and the XSLT stylesheet
are both coded on this template. The result is simply output as XHTML to the browser.
--->

<!--- Let's define a CFML based XML document object to store a simple XML instance --->
<cfxml variable="variables.theXmlDoc">
<!--- Remember not to include an XML declaration here, otherwise an error will be thrown --->
<greeting>
<string>Using XmlTransform() with parameters</string>
</greeting>
</cfxml>

<!--- Let's create a CFML based XML document object to store a simple XSLT stylesheet --->
<cfxml variable="variables.theXslDoc">
<!--- Remember not to include an XML declaration here, otherwise an error will be thrown. --->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
<!--- Define result tree output parameters --->
<xsl:output method="xml" indent="yes" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>

<!--- Let's create a single parameter with a default value for output later --->
<xsl:param name="cartoon-character">
<xsl:text>Butters Stotch</xsl:text>
</xsl:param>

<!--- Let's build the XHTML skeleton as literal result elements --->
<xsl:template match="/">
<html xml:lang="en">
<head>
<title><xsl:value-of select="greeting/string"/></title>
</head>
<body>
<h1><xsl:value-of select="greeting/string"/></h1>
<!--- Continue stylesheet processing --->
<xsl:apply-templates select="greeting"/>
</body>
</html>
</xsl:template>

<!--- Let's output the values of the previously defined parameters --->
<xsl:template match="greeting">
<p><xsl:value-of select="$cartoon-character"/></p>
</xsl:template>
</xsl:stylesheet>
</cfxml>

<!--- Let's now define the parameter we'd like to pass to the XSLT stylesheet. --->
<cfscript>
variables.theXslParams = StructNew();
StructInsert(variables.theXslParams, "cartoon-character", "Stan Marsh");
WriteOutput(XmlTransform(variables.theXmlDoc, variables.theXslDoc, variables.theXslParams));
</cfscript>

<!--- Alternatively you could also using the following syntax for building your structure --->
<cfscript>
variables.theXslParams = StructNew();
variables.theXslParams["cartoon-character"] = "Kyle Broflovski";
WriteOutput(XmlTransform(variables.theXmlDoc, variables.theXslDoc, variables.theXslParams));
</cfscript>

<!---
But remember that using "Object notation" to create your stucture will not work.
If your parameter name happens to contain a hyphen for separating words (param-name)
ColdFusion will throw an error. In any other event the default values defined within the XSLT
stylesheet would be used since this method doesn't even pass in parameters to begin with.
--->
<!---
// Uncomment this statement block if you like seeing ColdFusion MX exceptions being thrown.
<cfscript>
variables.theXslParams = StructNew();
variables.theXslParams.cartoon-character = "Kenny McCormick";
WriteOutput(XmlTransform(variables.theXmlDoc, variables.theXslDoc, variables.theXslParams));
</cfscript>
--->
Sarge said on Nov 14, 2005 at 8:19 AM :
The W3C link for XSL and XSLT mistakenly points to XPath (www.w3.org/TR/xpath/).
swood said on Feb 23, 2006 at 7:20 PM :
The XML and the XSL do not relate to each other, thus breaking the example. The XML doc is referencing the purchase of tools, while the XML is expecting "breakfast_menu/food". The result of the example is an empty, yellow table.
madDog17 said on Jun 6, 2007 at 10:20 AM :
XmlTransform() will NOT work with if you call cfFile() and your stylesheet imports any supporting stylesheets. It will find your top-level stylesheet but not the imports, and you will get an IO exception ("Had IO Exception with stylesheet file"). Mark Mandel has created a UDF that solves the problem, and you can find it here:
http://www.compoundtheory.com/?action=displayPost&ID=4.

J-P Stacey then extended Mark's work to create a more granular component that includes caching. You can find that here:
http://www.jpstacey.info/blog/2007/02/09/cfjavaxml-a-component-for-cached-xml-transformations/

Kudos to these gentlemen for fixing a problem and sharing the solution. Your work is much appreciated.
No screen name said on May 12, 2008 at 9:44 AM :
The dot notation is actually acceptable keeping in mind that .notation creates structures that have upper case keys. So, your xslt (which is case sensitive) must be looking for variables that are all upercase with xsl:param.

Coldfusion structures created with array notation keep the case in the key so work as expected.

 

RSS feed | Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/coldfusion/7/htmldocs/00000673.htm