Skip to main content
Ben Nadel at the jQuery Conference 2011 (Cambridge, MA) with: Niall Kader
Ben Nadel at the jQuery Conference 2011 (Cambridge, MA) with: Niall Kader

Converting XML To HTML Using ColdFusion And XSLT

By on
Tags:

As part of my exploration of XML, I've been playing around more with ColdFusion and XSLT. For this experiment, I am trying to encapsulate the data of an HTML page in XML. Then, I am using ColdFusion and XSLT to transform that XML document into an XHTML page. The ColdFusion XML document that I am starting off with contains:

  • Page Title
  • Meta Data information
  • Navigation elements
  • Primary Content information

Here is my ColdFusion XML document, built using the CFXML tag:

<!---
	Define the ColdFusion XML document object that
	will represent the data on an HTML page.
--->
<cfxml variable="xmlPage">

	<page>
		<title>
			Maria Bello Fan Site
		</title>

		<!--- Meta information. --->
		<meta>
			<keywords>
				maria bello,sexy girls,crazy sexy
			</keywords>
			<description>
				My Maria Bello fan site.
			</description>
		</meta>

		<!--- Primary navigation. --->
		<primarynav>
			<navitem
				text="Home"
				href="index.cfm"
				ison="true"
				/>
			<navitem
				text="Photos"
				href="photos.cfm"
				/>
			<navitem
				text="Videos"
				href="videos.cfm"
				/>
		</primarynav>

		<!---
			Primary page content. This will make up the bulk
			of the rendered page.
		--->
		<primarycontent>
			<![CDATA[
				<p>
					Welcome to my Maria Bello Fan Site. If you
					are like me, then you think she's just all
					kinds of sexy. I've spent many hours
					compiling this repository of images and
					videos for your (and my) enjoyment. Hope you
					enjoy and please check back soon.
				</p>

				<p>
					If Maria Bello were a cereal, she'd be
					magically babelicious.
				</p>
			]]>
		</primarycontent>
	</page>

</cfxml>

You will notice that I am keeping a lot of white space in my XML nodes (ex. keywords and description nodes). This is NOT recommended. This adds white space to the final XML node value. I am doing this purely for better code display, not as a best practice. Notice also that the primary content of the page is contained in a CDATA node. From what I have read about XSLT in general, it would appear that CDATA node type is not well liked (and perhaps not widely supported???); however, it seems to work quite nicely for XHTML type pages.

Then, once I have my ColdFusion XML document ready, I need to create my XSLT templates. These are the XML directives that will take the ColdFusion XML document and translate it in a divide-and-conquer fashion into the resultant data file which is, in our case, an XHTML page.

<!--- Define the XSL Transformation (XSLT). --->
<cfsavecontent variable="strXSLT">

	<!--- Document type declaration. --->
	<?xml version="1.0" encoding="ISO-8859-1"?>

	<xsl:transform
		version="1.0"
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

		<!---
			Tell the ColdFusion XSLT engine that we are
			going to be producing an HTML document and that we
			want to use indenting.
		--->
		<xsl:output
			method="html"
			indent="yes"
			/>

		<!---
			Bind this template to the root of the XML document
			using the "/" match attribute.
		--->
		<xsl:template match="/">

			<html>
			<head>
				<title>
					<!--- Output the page title. --->
					<xsl:value-of select="page/title" />
				</title>

				<!--- Output meta data template. --->
				<xsl:apply-templates select="page/meta" />
			</head>
			<body>

				<h1>
					<xsl:value-of select="page/title" />
				</h1>

				<!--- Output primary navigation. --->
				<xsl:apply-templates select="//primarynav" />

				<!--- Output page content. --->
				<xsl:apply-templates
					select="page/primarycontent"
					/>

			</body>
			</html>

		</xsl:template>


		<!--- Template for HTLM meta data. --->
		<xsl:template match="meta">

			<!--- Output met akeywords element. --->
			<xsl:element name="meta">
				<xsl:attribute name="keywords">
					<xsl:value-of select="keywords" />
				</xsl:attribute>
			</xsl:element>

			<!--- Output meta description element. --->
			<xsl:element name="meta">
				<xsl:attribute name="description">
					<xsl:value-of select="description" />
				</xsl:attribute>
			</xsl:element>

		</xsl:template>


		<!--- Template for the primary navigation items. --->
		<xsl:template match="primarynav">

			<ul id="primarynav">
				<!--- Loop over nav items. --->
				<xsl:for-each select="navitem">

					<li>
						<!--- Define the nav link HTML. --->
						<xsl:element name="a">
							<xsl:attribute name="href">
								<xsl:value-of select="@href" />
							</xsl:attribute>

							<!---
								Check to see if this link is on.
								If so, then we have to add the
								appropriate class.
							--->
							<xsl:if test="@ison = 'true'">
								<xsl:attribute name="class">
									on
								</xsl:attribute>
							</xsl:if>

							<!--- Text of link. --->
							<xsl:value-of select="@text" />
						</xsl:element>
					</li>

				</xsl:for-each>
			</ul>

		</xsl:template>


		<!--- Template for primary page content. --->
		<xsl:template match="primarycontent">

			<div id="sitecontent">

				<!---
					When outputting the page's primary content,
					make sure to DISABLE escaping so that our
					XHTML will come through properly.
				--->
				<xsl:value-of
					select="."
					disable-output-escaping="yes"
					/>

			</div>

		</xsl:template>

	</xsl:transform>

</cfsavecontent>


<!---
	Output the transformed XML page data into an
	HTML formatted web page using XSLT.
--->
#XmlTransform(
	xmlPage,
	Trim( strXSLT )
	)#

I have chosen to make this ColdFusion XML Transformation a bit more complicated than it needs to be for the purposes of forcing myself to learn more about the XSLT syntax. Some of this complexity is self-imposed, but also, XSLT is just a complicated syntax. For instance, instead of just writing an XHTML element and using some conditional logic to write attributes (such as adding an "active" class to an "on" navigational item), you have to use the xsl:element node and add each attribute as a descendent xsl:attribute node. A bit wordy if you ask me.

Also, notice that when I am outputting the CDATA, I am using the xsl:value-of attribute, disable-output-escaping. I have to do this other wise the XSLT engine will convert the HTML elements into escaped HTML elements.

Running the above code, we get the following page:

Convertted XML To XHTML Using ColdFusion And XSLT

XSLT is interesting. I think I am a little turned off by how complicated it seems to be. On the one hand, I like that you can take XML and convert it to any other kind of text-based data based on the Transformation files. But on the other hand, I feel like you can use ColdFusion to do this programmatically with much less stress. Plus, I think white space management is a big issue in XSLT. I like being able to space my ColdFusion code out in a way that makes me happy and produce quality output. I think that with XSLT, this is going to be a much harder task to accomplish.

Still not sure how I feel about it. I am gonna keep poking around; XSLT is HUGE! There are many functions and elements to be used. Luckily, it looks like ColdFusion only supports a subset of this functionality, so it won't be the beast that it could be. Plus, I am not sure I need to fully learn the syntax to get an idea of what is capable. The good thing is that it keeps me fresh with the XPath stuff I did a while back.

Want to use code from this post? Check out the license.

Reader Comments

15,640 Comments

@Dustin,

You maginificent bastard! That works (the normalize-space function). I had tried to use xsl:strip-space but couldn't get it to work. Maybe I wasn't doing it right it just wasn't supported in ColdFusion. Nicely done!

42 Comments

No problem!

The xsl:strip-space is to remove empty nodes from your XML so they don't display the whitespace of the empty node. The function name is a little misleading, I know for sure I was confused by it when I started using XSLT. From the link above:

"You can also automatically delete white-space only nodes in the input document by using xsl:strip-space."

w00t!

1 Comments

Yes, I agree. We just got the Google Mini, which comes with built-in xslt, which you can edit. It just seemed so much easier to return the results in XML, convert them to a query, and then manipulate them through ColdFusion.

This post helped reaffirm my decision.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel