Accessing XML Nodes Having Names That Contain Dashes In ColdFusion

Posted April 6, 2010 at 1:29 PM by Ben Nadel

Tags: ColdFusion

ColdFusion has always made working with XML documents very easy. By implicitly wrapping the underlying XML DOM nodes in pseudo node collections, we've always been able to easily access XML nodes using struct (dot) and array (bracket) notation. For example, accessing the name of the third girl in an XML document could look as straightforward as something like this:

girls.girl[ 3 ].name.xmlText

As you can see, ColdFusion allows us to think about XML node collections as both named and ordered collections of like-nodes.

Most of the time, this is exactly what we need and it works perfectly. But, as Simon Hume brought up on Twitter today, when your XML node names contain a dash, you have to be a bit more careful in the way you define your node paths. Going back to the previous example, if we had the node, "girl-name", rather than, "name," we might be tempted to try following node path:

girls.girl[ 3 ].girl-name.xmlText

When ColdFusion sees this, however, it will throw the following error:

Element GIRL is undefined in a Java object of type class coldfusion.xml.XmlNodeMap.

This is happening because ColdFusion doesn't see the dash as part of the node name; rather, ColdFusion sees this dash as a mathematical operator in the following equation:

((girls.girl[ 3 ].girl) - (name.xmlText))

To get ColdFusion to see the dash as part of the node name, we have to "escape" it, for lack of a better term. To do so, we either have to use array notation and define the node name as a quoted string; or, we have to use xmlSearch() where we can deal directly with the underlying document object model. The following code demonstrates both of these approaches:

  • <!---
  • Create an XML document that has some node with names that
  • contain dashes.
  • --->
  • <cfxml variable="girls">
  •  
  • <girls>
  • <girl>
  • <given-name>Tricia</given-name>
  • <private-name>Pookie-bear</private-name>
  • </girl>
  • <girl>
  • <given-name>Joanna</given-name>
  • <private-name>Sugar-butt</private-name>
  • </girl>
  • </girls>
  •  
  • </cfxml>
  •  
  •  
  • <!---
  • Use ColdFusion's XML node wrappers to access the pseudo-node
  • collection based on names. Notice here that we are wrapping the
  • node name in quotes and using array-notation in the node path.
  • --->
  • <cfset tricia = girls.girls.girl[ 1 ][ "private-name" ].xmlText />
  •  
  • <!---
  • In this version, we'll use xmlSearch(). Since xmlSearch() is
  • using the native XML DOM structure, we don't need to "escape"
  • the dashed name in any way.
  • --->
  • <cfset joanna = xmlSearch(
  • girls,
  • "/girls/girl[ 2 ]/private-name/"
  • ) />
  •  
  • <!---
  • Output the girl's private names as extracted from the XML
  • document object model.
  •  
  • NOTE: Because xmlSearch() returns an array, "joanna" is the XML
  • node array at this point, not the actual text value.
  • --->
  • <cfoutput>
  •  
  • Tricia: #tricia#
  • <br />
  • <br />
  • Joanna: #joanna[ 1 ].xmlText#
  •  
  • </cfoutput>

As you can see in the above code, our ColdFusion XML document has the dash-containing node, "private-name." In the first approach, we use array notation and quote the node name. In the second approach, we use xmlSearch() in which no "escaping" is necessary. Running the above code, we get the following page output:

Tricia: Pookie-bear

Joanna: Sugar-butt

As you can see, both approaches work fine when dealing with XML nodes that contain dashed-names. The technique you end up using is going to depend on the situation. Using ColdFusion's pseudo node wrappers is typically easier when we know that the structure of the XML document will be fairly static. But, if the XML document can be more dynamic, xmlSearch() gives us a lot of flexibility and power in how we traverse the underlying node tree.


You Might Also Be Interested In:



Reader Comments

Apr 6, 2010 at 1:53 PM // reply »
10,743 Comments

You could also use native XML traversal to get around this:

xmlRoot.xmlChildren[ 1 ].xmlChildren[ 2 ].xmlText

... but this is pretty much unreadable. As such, I left it out of the convesation; but, I figured I'd throw it here into the comments as an after-thought.


May 17, 2010 at 3:57 PM // reply »
1 Comments

I ran into this issue with an XML attribute, here is how I worked around it...

<cfset example = XmlRoot.XmlAttributes["page-size"]>

...where "page-size" is an XML attribute of the root node. I figure this may be somewhat easier to follow as there is no extraneous array notation, or XML searching involved.


May 17, 2010 at 4:02 PM // reply »
10,743 Comments

@Justin,

Ah, great points - the array notation works both for element nodes as well as for attribute nodes. Excellent tip.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 16, 2012 at 8:18 PM
Best Of ColdFusion 10 Contest Entry - HTML Email Utility
Just found this, looks good! I'm trying to run it on local, it's the 64bit version and I'm experiencing horrible lag. On average the generate.cfm processes the content change in 60-90 seconds. I've ... read »
May 16, 2012 at 6:40 PM
Maintaining Sessions Across Multiple ColdFusion CFHttp Requests
I am trying to integrate this CFHTTPsession into an application that will log into zeekrewards.com to post ads and I am not having any luck. The code works perfectly for logging into other websites, ... read »
May 16, 2012 at 2:44 PM
Creating A Sometimes-Fixed-Position Element With jQuery
Thank you, very useful technique! Worked like a charm. ... read »
May 16, 2012 at 1:58 PM
Movies As A Religious Experience
Acting can, in a way, ruin the movie-goer's experience. I used to be able to get so caught up in movies and their plots, and totally engaged. But lately, I haven't been able to as much with a lot o ... read »
May 16, 2012 at 1:52 PM
The Science Of Optimal Post-Exercise Nutrition
children of this age eat very less vegetables so u can opt for salads they will like it also carrot ,cucumber,onion and as far as pulses are concerned u can boil them ,give him along with mashed rice ... read »
May 16, 2012 at 1:34 PM
Strange ColdFusion JRUN Stack Overflow Error
Hey, Recently I updated my jrun4 using the latest updater 7 and now i am having memory issues :(:(:( any help is appreciated ... read »
May 16, 2012 at 9:56 AM
ColdFusion 10 Beta, Apache Tomcat, And Symbolic Links On Mac OSX
Hi, Now that ColdFusion 10 is out I have stumbled over this as well and I cannot figure out the proper solution. We're running virtual hosts via Apache2; the ColdFusion-applications store their fil ... read »
May 15, 2012 at 6:03 PM
Movies As A Religious Experience
@Ben, I don't know whether you'd consider this a religious observation, but it seems to me, in a sense, movies multiply how many lives we get to have. Each movie is like a little extra life we get ... read »