Text Nodes DO Always Exist in a ColdFusion XML Document

I was caught off-guard by the title of Ben Nadel's recent blog post "Text Nodes Do Not Always Exists in a ColdFusion XML Document." After reading his article, I realized he was mistaken.

Here's the code he gave us:


<!--- Create a ColdFusion XML document. --->
<cfxml variable="xmlGirl">
    <girl>
        <name>Hayden Panettiere</name>
        <age>18</age>
        <height></height>
        <weight></weight>
        <description>
            Hayden played Claire, the Cheerleader, on the hit
            Fox television show, Heroes.
        </description>
    </girl>
</cfxml>
<!--- Dump out XML document. --->
<cfdump
    var="#xmlGirl#"
    label="Girl: Hayden Panettiere"
    />

You'll notice that there area two empty elements, "height" and "weight." Using ColdFusion's <cfdump var="#yourXmlVariableNameHere#" /> feature displays some awesome information. Using the code above, the CFDump shows us this:

Now, keep in mind, this is only the "Short Version" of what is actually in the dump. If you click on the title bar of the CFDump, it will expand to show evern more information in the "Long Version." Here's a cropped version:

Both the short and long versions show there are a number of element nodes for each xml element. Just because the element is "empty" does not mean it doesn't exist. It's just, well ... empty.

I even ran a little test with this code:


<cfoutput>
#xmlGirl["girl"]["name"][1]#<br />
#xmlGirl["girl"]["age"][1]#<br />
#xmlGirl["girl"]["weight"][1]#<br />
#xmlGirl["girl"]["height"][1]#<br />
#xmlGirl["girl"]["description"][1]#
</cfoutput>

This produced:

Obviously, the line-breaks are showing up,and when I viewed the source, I could see the elements being produced:

And both "weight" and "height" are there, but they're just empty elements.

As Ben pointed out in his article, when an xml document has an empty element, you end up with a scenario akin to NULL's in a SQL database. Unfortunately, you can't just test for NULL or an empty element with closed quotes. However using the magic of XML Path Language, XPath, you can write some fairly sophisticated arguments.

In fact, Ben was on the "Path" (no pun intended) to finding the answer, he only needed to modify his XmlSearch() to include finding empty text nodes.

Here's my modified XPath statement to show only empty text() nodes:


<!--- this returns only empty text() --->
<cfset arrNodes = XmlSearch(xmlGirl, "//*[ (boolean(text()) = 0) ]") />
<!--- Output names of nodes. --->
<cfoutput
>

<cfloop index="
xmlNode"
        array="
#arrNodes#">
#xmlNode.XmlName#<br />
</cfloop>
</cfoutput>

Using this method, you could also test for text() nodes that aren't empty:


<!--- this returns only non-empty text() --->
<cfset arrNodes = XmlSearch(xmlGirl, "//*[ (boolean(text()) = 1) ]") />
<!--- Output names of nodes. --->
<cfoutput
>

<cfloop index="
xmlNode"
        array="
#arrNodes#">
#xmlNode.XmlName#<br />
</cfloop>
</cfoutput>

Obviously, you could combine the statements to find all text() nodes:


<!--- this returns ALL text() --->
<cfset arrNodes = XmlSearch(xmlGirl, "//*[ (boolean(text()) = 0) or (boolean(text()) = 1) ]") />
<!--- Output names of nodes. --->
<cfoutput
>

<cfloop index="
xmlNode"
        array="
#arrNodes#">
#xmlNode.XmlName#<br />
</cfloop>
</cfoutput>

Enjoy!

Comments

Looks good. I think when it comes down to it, we are more or less doing the same thing. I used the not() method which toggles a boolean. You use the boolean() method to make a boolean comparison. Either way, we are dealing with booleans on the text node.

But, like I said, I really need to do a better exploration of the XPath functions. I bet there is a lot of functionality that I haven't leveraged yet.
# Posted By Ben Nadel | 5/22/08 10:46 AM
@Ben,
When you have a chance, take a look at the W3C site on XPath. Actually, I reference their Core Function Library and Expressions when I need to. Here's a link to Boolean Functions: http://www.w3.org/TR/xpath#section-Boolean-Functio...
# Posted By Stephen Withington | 5/22/08 12:35 PM
@Stephen,

Thanks for the link. I usually check out the W3C Schools XPath tutorials, but sometimes they are not very explanatory. The link you have seems a bit more in depth. Thanks.
# Posted By Ben Nadel | 5/23/08 8:25 AM

© 2024, Stephen J. Withington, Jr.  |  Hosted by Hostek.com

Creative Commons License   |   This work is licensed under a Creative Commons Attribution 3.0 Unported License.