Wednesday, April 19, 2006
« Deserializing Configuration File Section... | Main | SQL Server 2005 SP1 Out Today »

I don't claim to be an XML/XPath expert, but I can definitely hold my own - at least so far.  I just wanted to share something I was doing today in the hopes that someone might also benefit.

By and large, developers (and by developers, I mean people, though they're not always synonymous) use XPath with positive assertions.  What I mean is that XPath is used to query Xml documents looking for information they know or expect to exist.

For instance, the following XPath query will return the child nodes beneath the family element that contains a lastname attribute value of 'Rogers'

/family[@lastname='Rogers']/*

Removing the trailing '/*' such that the query is /family[@lastname='Rogers'] will return the family nodes that have a lastname attribute of 'Rogers'

Suppose further that you wanted to retrieve all family elements that had a value other than Rogers, you'd simply change the equality operator

/family[@lastname!='Rogers']

Ok, no magic.  It's all rudimentary, simple XPath.

However, what if you wanted to perform a negative assertion?  That is, what if you wanted to get the family elements that didn't have a lastname?  I'm not talking about an empty lastname (i.e. <FAMILY lastname="" />), I'm talking about all of the family elements that are missing the lastname attribute entirely (i.e. <FAMILY />).

I don't know of a way to solve this by simply using straight element/attribute syntax (but then again, I don't pretend to know much of anything about it in the first place).  The solution is actually quite simple, but you have use a function.

/family[count(@lastname)=0]

[EDIT 04/20/2006: Corey Kaylor left a comment that I'd like to share]
I had tried many variations on this exact theme, but failed to try the not() function.  Thanks Corey!
A better solution is this:

/family[not(@lastname)]

That simple query allows you to find all nodes with the specified name that don't have the lastname attribute.  Pretty slick.  This is just tapping the surface, because there's a whole bunch more that you can do.  I simply wanted to record it so I wouldn't forget.  Simple.  Easy.  I like it.

Wednesday, April 19, 2006 2:29:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback