Using XPath To Select A Node That Does Not Contain Another Node In ColdFusion

Posted March 25, 2010 at 10:09 AM by Ben Nadel

Tags: ColdFusion

Just a quick post on XPath in ColdFusion. This morning, when I was writing about screen-scraping movie showtimes off Fandango.com, I had to use an XPath query that looked for an XML node that did not contain another XML node. In the past, I've blogged about gathering nodes that did not contain a text node (or a given text value); but, I don't think I have ever talked about getting nodes that did not contain a given element node. As such, I wanted to throw together a very brief example of how this is done.

To quickly recap, XPath queries can contain predicates. These are qualitative queries, wrapped in brackets, that filter the given node into or out of the resultant node-set. For example, in the given XPath query:

//a[ @rel = 'home' ]

... we are looking for an "a" element node that has an href attribute that contains the value "home." The predicate, in this case, is the relative query, "[ @rel = 'home' ]". A predicate can contain just about anything so long as that can be boiled down to a truthy / falsey value.

If we want to search for a node that does not contain another node, we can use a negated XPath predicate. Populated node sets are truthy values. As such, if we want to find a node that does not contain a given node, we need to negate the predicate in which the node does contain the given node. In XPath, this negation can be performed by the not() function.

To see this in action, I am going to select from a collection a movies all movies that are not musicals:

  • <!--- Create the XML document. --->
  • <cfxml variable="movies">
  •  
  • <movies>
  • <movie>
  • <name>Terminator</name>
  • <genre>
  • <action />
  • <adventure />
  • </genre>
  • </movie>
  • <movie>
  • <name>De-Lovely</name>
  • <genre>
  • <musical />
  • </genre>
  • </movie>
  • <movie>
  • <name>Sex Drive</name>
  • <genre>
  • <comedy />
  • </genre>
  • </movie>
  • </movies>
  •  
  • </cfxml>
  •  
  •  
  • <!--- Query for all movies that are not musicals. --->
  • <cfset nonMusicals = xmlSearch(
  • movies,
  • "//movie[ not( genre/musical ) ]"
  • ) />
  •  
  • <!--- Output the selected movies. --->
  • <cfdump
  • var="#nonMusicals#"
  • label="Non-musical Movies."
  • />

As you can see, our XPath query is using the following search:

//movie[ not( genre/musical ) ]

Within each movie node, we are checking to see if the node contains the ancestor genre, "musical". Of course, since those are the movies that we specifically do not want to select, we then use the not() function to turn any matching musical node set from a truthy value into a false boolean value. This false then filters the given movie out of the resultant node set, returning only movies that do not contain the musical element node.

When we run the above code, we get the following CFDump output:

 
 
 
 
 
 
Selecing An XML Node With XPath That Does Not Contain Another Given Node. 
 
 
 

As you can see, De-Lovely, a musical, was not returned in the resultant node set. This is a minor, but powerful feature of XPath.




Reader Comments

Mar 25, 2010 at 7:38 PM // reply »
67 Comments

It's good to see there's always something new I can learn about XPath. Good post. Cheers.

--
Adam


Mar 26, 2010 at 7:57 AM // reply »
11,238 Comments

@Adam,

No problem my man. XPath is some cool stuff.


Nov 3, 2012 at 1:27 AM // reply »
1 Comments

hi,
This is the one which help me allot . i am very thankful.


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
May 20, 2013 at 11:45 AM
Using jQuery's Animate() Step Callback Function To Create Custom Animations
This is really useful. I found out that you don't actually have to use a dummy css property (surprisingly). To animate a property in a linear-gradient for instance I did this this.css('someLinearGra ... read »
May 20, 2013 at 10:51 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Josh, Oh snap! You're totally right! I'm not sure I've ever tried that. I did know that you can call a number of other array-methods on ColdFusion query columns: http://www.bennadel.com/blog/167 ... read »
May 20, 2013 at 10:45 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Ben - I believe you can achieve the same functionality with ColdFusion's built in ArrayToList() function. ArrayToList( users[ "id" ] ); ... read »
May 20, 2013 at 10:21 AM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
Is there any error logging and handling framework in angularjs, if not then in what way I can do this. ... read »
May 19, 2013 at 2:31 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
It's funny really just how well that image describes the way I would imagine most people that go with angular for some project is. I have had a similar roller-coaster ride with it as well, but not qu ... read »
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools