Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at the New York ColdFusion User Group (Jul. 2008) with: Clark Valberg and Simon Free

Using XML Style Name Space Attributes In ColdFusion

By Ben Nadel on
Tags: ColdFusion

I was just reading over on Truths and Lies a post by Christ Scott about using Meta Data in ColdFusion. I have used meta data before and it is pretty sweet-ass. But what was very interesting to me about this post was a comment by Scott Arbeitman who states that you could use XML style name space attribute notation (as in "cs:" for Cold Spring) in ColdFusion. This is pretty interesting. To test this out, I did a little demo for myself:

  • <!---
  • Define a standard ColdFusion user defined function but
  • add some "kinky" name space attributes to the declaration.
  • --->
  • <cffunction
  • name="Test"
  • access="public"
  • returntype="string"
  • output="false"
  • hint="Returns a string"
  •  
  • <!--- Add custon attributes for kinky name space. --->
  • kinky:author="Ben Nadel"
  • kinky:datecreated="2007/01/30"
  • >
  •  
  • <cfreturn "This is a test for XML style attributes" />
  • </cffunction>

Notice that the Author and DateCreated attributes are for the "kinky" name space only. Now, if I dump out the function object:

  • <!--- Dump out the UDF. --->
  • <cfdump
  • var="#VARIABLES.Test#"
  • label="Test() UDF"
  • />

... you will see that nothing has changed:


 
 
 

 
XML Style Meta Data In ColdFusion  
 
 
 

However, if you dump out the meta data for the UDF:

  • <!--- Dump out meta data. --->
  • <cfdump
  • var="#GetMetaData( VARIABLES.Test )#"
  • label="Test() UDF Meta Data"
  • />

... you will see that the XML style attributes are keys in the meta data structure:


 
 
 

 
XML Style Meta Data In ColdFusion  
 
 
 

Very interesting. Once it is in the meta data object, it is very easy to access as a structure key:

  • <!--- Get the UDF meta data. --->
  • <cfset objMetaData = GetMetaData( VARIABLES.Test ) />
  •  
  • <!--- Get the author. --->
  • <cfset strAuthor = objMetaData[ "kinky:author" ] />

Now, I know ZERO about name spaces (and not much more about XML) and in fact, I just wrote a blog entry about stripping them out, so I don't know what this would be used for. But I do like the idea of being able to have attributes that don't get confused with the inherent ColdFusion attributes (which I guess might be the whole idea behind name spaces).




Reader Comments

Excellent use of the 'kinky' namespace! I was discussing this strategy a while back with Peter Farrell and suggested using the 'titties' namespace. You can be 100% positive adobe's never ever ever gonna use that!

Reply to this Comment

Exactly. Namespaces like that future-proof your code in case adobe wants to attributes later. Also, its also more obvious that you are doing something special (kinky) when you prefix your attributes like this.

It also allows you to use the name attribute names as built-in Coldfusion attributes.

I've seen a framework (Transfer, I believe) that has two attributes for return types of functions. One is always "any", probably for performance reasons, and the other is the real CFC type, probably for documentation.

Reply to this Comment

@Chris,

Ha ha ha ha ha ha ha. Excellent :)

@Scott,

That makes sense to me. I guess my confusion has always been in that things that are "name-spaced" are things that don't conflict as-is. However, the future-proofing makes much more sense.

You don't happen to know why name-spaces complicated things like XPath searches do you??

Reply to this Comment

XML namespaces are supposed to prevent clashes within tag and attributes in different contexts. For example, in a soap request, some data is related to the soap protocol while most of it is probably the data you need.

If you strip out namespaces and search for elements, there is a chance you will find data that don't care about.

Searching for nodes with namespace prefixes is as simple as using XPath with the prefix included in your search string. For example: "//myprefix:mynode".

ColdFusion's XPath implementation has a "feature" where empty namespaces must be prefixed with the empty namespace prefix. For example: ":/mynode". You'll know you're dealing with an empty namespace as compared to no namespace at all if you see the attribute xmlns="URI" in your document.

Reply to this Comment

Scott,

I have taken a look at your comments and the comments made on my previous post... and I still cannot get it to work. If you take a look at this:

http://www.bennadel.com/index.cfm?dax=blog:494.view

.. and the example in it, can you please help me out. I cannot figure out why this expression is not working:

//:searchFor

is not finding the non-namespaced xml node. I get this error:

An error occured while Transforming an XML document. Prefix must resolve to a namespace:

Any suggestions?

Reply to this Comment

Awesome.

I have a question that I'm hoping someone can help me with.

I'm reading in an RSS feed and creating a fresh one using CF8, compliant with iTunes namespace for podcasting.

I need to add in ns details like "itunes:author" but CF isn't liking the way I'm doing it.
The feed compiles perfectly until I start placing these in, but I hope there is a way around it.

A sample code is below. Thank you very much in advance for any help you can provide.

<cfset tempxml.rss.XmlChildren[1].XmlChildren[i].enclosure = XmlElemNew(tempXml, "enclosure")>
<cfset tempxml.rss.XmlChildren[1].XmlChildren[i].enclosure.XmlAttributes["url"] = "#blogPosts.linkhref[i]#">
<cfset tempxml.rss.XmlChildren[1].XmlChildren[i].enclosure.XmlAttributes["length"] = "#blogPosts.linklength[i]#">
<cfset tempxml.rss.XmlChildren[1].XmlChildren[i].enclosure.XmlAttributes["type"] = "#blogPosts.linktype[i]#">

<cfset tempxml.rss.XmlChildren[1].XmlChildren[i].itunes:duration = XmlElemNew(tempXml, "itunes:duration")>
<cfset tempxml.rss.XmlChildren[1].XmlChildren[i].itunes:duration.XmlText = "#Trim("#XMLFormat(blogPosts.itunes_duration[i])#")#">

Many thanks,

Matt

Reply to this Comment

@Matt,

While I love XML more than chocolate, I am not very good at all with namespaces. What if you tried this:

<cfset tempxml.rss.XmlChildren[1].XmlChildren[i][ "itunes:duration" ] = XmlElemNew(tempXml, "itunes:duration")>
<cfset tempxml.rss.XmlChildren[1].XmlChildren[i][ "itunes:duration" ].XmlText = "#Trim("#XMLFormat(blogPosts.itunes_duration[i])#")#">

Notice that I am putting "itunes:duration" in a quoted struct-key. Not sure if that will work, but it should be a step in the more correct direction.

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
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.