Home > ColdFusion, Errors, code > XMLSearch in ColdFusion – Unusual Behavior

XMLSearch in ColdFusion – Unusual Behavior

Well, maybe not completely unusual behavior, but I figured I would document my findings for others anyway.

ColdFusion allows managing of XML documents with relative ease. From the dot notation for traversing an XML document to the various functions to manipulate the document, just about everything is pretty simple when using ColdFusion. Recently, however, I came across an issue with using XMLSearch() It’s probably more of my (previous) understanding of the function call itself rather than it not working correctly, but it still seems a little unusual behavior to me.

I had an XML document that parsed fine.

<cfset INST.parsedData = xmlParse( INST.config ) />

From here I did an XMLSearch for a certain type attribute in my parsed document:

(I grab the first item of the array and set it back to itself so I’m not creating an extra temp variable. The @type is always present in the file so no error will be thrown)

<cfset INST.subObject = xmlSearch( INST.parsedData, "//object[ @type= '" & INST.eachType & "']/") />
<cfset INST.subObject = INST.subObject[ 1 ] />

From here, I wanted to grab a specific item from INST.subObject, but doing the following would always return all of the property nodes with identity=”true” rather than just those specific to the INST.subObject variable

<cfset INST.identityProperty = xmlSearch( INST.subObject, "//property[ @identity= 'true']") />

I guess that the INST.subObject is actually just a pointer of some sort to the original document and when passing the xmlDoc argument into xmlSearch, it then uses the whole original document to perform the actual search.

The solution isn’t too difficult, but may not be completely apparent at first. You just have to create a new xml document of the returned data, thus wiping out any references to the original parsed XML document.

<cfset INST.subObject = xmlparse( tostring( INST.subObject[ 1 ] ) ) />
<cfset INST.identityProperty = xmlSearch( INST.subObject, "//property[ @identity= 'true']") />

INST.identityProperty will now contain the one node within INST.subObject that has an attribute “identity” of true (rather than returning all nodes in the original document with attribute “identity” of true).

Categories: ColdFusion, Errors, code Tags: , ,
  1. July 10th, 2009 at 14:55 | #1

    @Gareth,

    You made one minor mistake that is causing the headache. Yes, the search results are references to elements STILL in the primary document tree. As such, you have to be careful about how you start you subsequent searches. If you use this:

    //property[ @identity= 'true']

    … the “//” means “anywhere in the document.” Well, since the search results are still *part* of the original document, the “//” will search as if you are searching of the main document.

    To stay *within* the subset of the search results, I use this:

    ./property[ @identity= 'true']

    … the “./” means “starting at this node” perform the search. You could also just forget the slash altogether:

    property[ @identity= 'true']

    … this should be the same thing (like folder paths).

  2. Gareth
    July 10th, 2009 at 15:16 | #2

    @Ben,
    Ah, I had another go (now I’ve got the official Ben Nadel Approved Code ;) ) and it looks like it’s because I have another node in there.

    ./properties/property[ @identity='true' ]

    found it.

    Is there a way to say “find it anywhere in my subdocument” rather than having to specify all nodes on the way to the node?

  3. July 10th, 2009 at 16:41 | #3

    Essentially there are three types of ways to find something based on the start of the search path:

    “/” -> Starting at the root document. As in:
    /rootnode/subnode

    “//” -> Anywhere in the document. As in:
    //subnode

    “./” -> (same as not putting any slash at all) Starting at the current context node.

  4. August 4th, 2009 at 10:31 | #4

    I just stumbled upon this same issue today and was pleased to find such a simple solution. Thanks for the (unknowing) help.

  5. Gareth
    August 4th, 2009 at 19:59 | #5

    Glad to hear it helped you out. It’s nice to know that someone else didn’t have to pummel away at their code trying to make it work :)

  1. No trackbacks yet.