If you have an XML Doc:
<employees>
..<employee>
....<empid>123</empid>
..</employee>
..<employee>
....<empid>456</empid>
..</employee>
</employees>
I want a list of empid values. I can use XMLSearch to get an array of empids, and loop over it to listappend the values, but I dont want to have to loop over the nodes. I really wanted to use StructFindKey(myxml,"empid","all") but that function cant be run against xml objects. Know of a low-intensive way to get a list of empids?
I feel your pain. I wish that ColdFusion's XmlSearch() function didn't always return node structures. The problem is that returning a non-node structure is not useful at all for further XmlSearch() calls since the returned values lose all XML DOM context. In fact, they wouldn't even be part of the XML document object at all (since simple values are copied by value, not reference).
That being said, the key to making something like this "low-intensive" is by encapsulating the functionality in such a way that it is both powerful and very easy to utilize. To help you out, or at least give you some ideas, I have created a little ColdFusion component called XmlUtility.cfc. This ColdFusion component utility has two functions:
This function takes your ColdFusion XML document and your XPath value and returns an array of the values of the nodes that get matched. If an element node is returned, this function grabs the XmlText. If an attribute node is returned, this function grabs the XmlValue. There is also a third, optional argument which will limit the returned values to be numeric (this is used primariliy by the other method of this ColdFusion component).
This function takes your ColdFusion XML document, your XPath value, and returns the given aggregate of the generated value array. The available aggregates are Min, Max, Sum, and Avg (average).
Ok, so now let's take a look at this ColdFusion XML stuff in action. To test with, we must build a ColdFusion XML document object:
Launch code in new window » Download code as text file »
Notice that this XML document has a mix of attributes and straight up text node values. Now, we can create an instance of the XmlUtility.cfc ColdFusion component and start testing. To being, let's tackle the problem that you present - getting all the text values. For my demo, I will grab the names of all the girls that are considered "legal":
Launch code in new window » Download code as text file »
Here, we are getting all the Name node text values based on those that have sibling Age nodes who's text value greater than or equal to 18. Running the above code, we get the following CFDump output:
| | | | ||
| | ![]() | | ||
| | | |
I am getting girl names, but this could just have easily been the EmpID node values that you have in your example.
Ok, now let's take a look at the Aggregate functionality. This is basically a short cut of getting the value array and then running an array method on it yourself. For this example, let's get the maximum age of all the girls in the ColdFusion XML document:
Launch code in new window » Download code as text file »
Running the above code, we get the following output:
Age Max: 25
Like I said, there is a certain amount of work that needs to be done to perform operations like this in ColdFusion, but at least if you encapsulate it into a user defined function (UDF) or a ColdFusion component like my XmlUtility.cfc, it becomes easier.
Here is the XmlUtility.cfc code:
Launch code in new window » Download code as text file »
I hope this helps you in some way.
Download Code Snippet ZIP File
Comments (4) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Glad I could inspire you! Ill try it out now.
Tim
Posted by Tim on Aug 27, 2007 at 11:13 AM
Did I miss a link to your XmlUtility.cfc?
Posted by Tim on Aug 27, 2007 at 11:31 AM
Oh my god! I am such an IDIOT! I forgot to post the code. Give me two seconds :(
Posted by Ben Nadel on Aug 27, 2007 at 11:36 AM
Ok, it's in there now. Really sorry about that... a bit embarrassing :)
Posted by Ben Nadel on Aug 27, 2007 at 11:38 AM