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 »
11,314 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 »
11,314 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
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 18, 2013 at 3:39 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
Hi Ben, THANKS! While not bleeding edge, it is new to me & I like learning new things every day! ... read »
Jun 18, 2013 at 12:30 PM
Disabling Auto-Correct And Auto-Capitalize Features On iPhone Inputs
Also spellcheck="false" should be mentioned as part of html5 specs ... read »
Jun 18, 2013 at 8:40 AM
Using Named Functions Within Self-Executing Function Blocks In Javascript
Hi Ben, you forgot to mention the most important thing for named self-executing functions - they can be referenced by name ONLY inside their execution context (which is parens in this case), it mean ... read »
dee
Jun 18, 2013 at 7:01 AM
My Safari Browser SQLite Database Hello World Example
hai ben, this program is really good i could understand the concept but i dint know how to save it and how to open it as you have done in the video can u give that details pls ... read »
Jun 18, 2013 at 6:04 AM
Clearing Inline CSS Properties With jQuery
Thanks a lot for for post! It helped me a lot... after being stuck since 24 hrs.. found solution from your post. Thanks again! ... read »
Jun 18, 2013 at 2:31 AM
SOTR 2013 - The Best Conference I Never Went To
I keep watching it, should keep me happily distracted until SotR14 ;) ... read »
Jun 17, 2013 at 9:45 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, As I was reading what you wrote, it occurred to me that maybe I do something similar to that in some of my client-side code. In an application I'm working on, there are a bunch of unrelated ... read »
Jun 17, 2013 at 9:36 PM
Object Thinking By David West
@Jonah, Please, don't feel bad at all. I appreciate all that you have contributed to the conversation. And, the more points of view I get, the more confident I am that I will some day, some how und ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools