| Discussion Home | About | Threads By Date | Search |
Title
CF10- XMLsearch() & XMLTransform() now support Xpath 2
Content
We don't often work with XML now, most of the data exchange is done through JSON. Most of the APIs that supported XML and JSON said XML is still a data type that will inevitably be a part of our lives for some time are now dropping XML support. That's why it's actually kind of exciting that ColdFusion 10 now supports XPath 2.0 in the xmlSearch() and xmlTransform() functions. I agree that I am decades behind developers who rule the web, but sill, after some Googling I worked out to put forward a demo of the functionality that is now available in ColdFusion 10.
XPath is used to navigate through elements and attributes in an XML document. XPath is a major element in W3C's XSLT standard - and XQuery and XPointer are both built on XPath expressions.
Code
<!---
Create an XML document on which to test new XPath 2.0
functionality support.
--->
<cfxml variable="bookData">
<books>
<book id="101" rating="4.5">
<title>ZAVIA</title>
<author>Ashfaq Ahmad</author>
<published>Sep 1, 2004</published>
<isbn>9693515870</isbn>
</book>
<book id="201" rating="4">
<title>Butt Parey</title>
<author>Dr. Younis Butt</author>
<published>November 1, 2007</published>
<isbn>9693510151</isbn>
</book>
<book id="301" rating="4.5">
<title>KHARMASTIAN</title>
<author>DR.MUHAMMAD YOUNAS BUTT</author>
<isbn>9693510488</isbn>
</book>
</books>
</cfxml>
<!--- Groovy - now let's execute some XML Path queries. --->
<cfscript>
// Get all of the ratings that are greater than or equal to 4.5.
results = xmlSearch(
bookData,
"//book/@rating[ number( . ) > 4.0 ]"
);
// Get the average rating of the reviews.
results = xmlSearch(
bookData,
"avg( //book/@rating )"
);
// Get a compoud result of the Title and Author notdes. Notice
// that we can now create divergent results in the SAME path.
// We don't need to create two completely different paths.
results = xmlSearch(
bookData,
"//book/( title, author )"
);
// Get all of the book's children EXCEPT for the ISBN number.
// XPath 2.0 introduces some intesting operators like "except",
// "every", "some", etc.
results = xmlSearch(
bookData,
"//book/( * except isbn )"
);
// XPath 2.0 now uses sequences instead of node-sets which allow
// for more interesting data combinations. This only gets the
// nodes from one collection that are NOT in the other collection.
// We're using inline branching and merging!
results = xmlSearch(
bookData,
"//book/( (title, published) except (isbn, published) )"
);
// Get all of the ISBN numbers that use a 10-digit ISBN. XPath
// 2.0 now supports regular exprdssion functions like matches(),
// replace(), and tokenize() -- thought it is quicky and a
// bit limited in patterns.
results = xmlSearch(
bookData,
"//book/isbn[ matches( text(), '^\d{10}$' ) ]"
);
// Iterate over one collection and map it onto the resultant
// collection. We can now iterate inline within a path.
results = xmlSearch(
bookData,
"for $b in (//book) return ( $b/published )"
);
// We can now pass in params into our xmlSeach() calls. Notice
// that the key, "title" is quoted - that is because XPATH is
// case-sensitive.
results = xmlSearch(
bookData,
"//book/title[ . = $title ]",
{
"title": "KHARMASTIAN"
}
);
// Get the given book, no matter what the casing. FINALLY, we
// can case-insensitive searching in XML :)
results = xmlSearch(
bookData,
"//book[ upper-case( title ) = 'Butt Parey' ]"
);
// Debug the results.
writeDump( results );
</cfscript>