Will Sappington wrote:
I searched the archives for "xpath result" (unquoted) and didn't get any useful hits so:The SimpleXPathAPI example does this after establishing the context node: // OK, let's evaluate the expression... const XObjectPtr theResult( theEvaluator.evaluate( theDOMSupport, theContextNode, XalanDOMString(argv[3]).c_str(), thePrefixResolver)); assert(theResult.null() == false); cout << "The string value of the result is:" << endl << theResult->str() << endl << endl; It would appear from this that the test for an unsuccessful XPath evaluation is theResult.null() returning true. However, if I evaluate an XPath expression containing an element or attribute that is not in the file, that test fails - .null() returns false - and after converting the result to a regular C char string, it is empty, zero length. If I give the SimpleXPathAPI sample program an expression that will not match, it prints "The string value of the result is ", indicating thatit too got a zero length result instead of null.
XObjectPtr is a smart-pointer class, so the call to the null() member function just determines whether or not it's pointing to an XObject instance. In this case,
Any calls made using the -> operator are passed on to the underlying XObject instance. The XObject class holds the actual result of the evaluation. It's type depends on the type of the XPath expression you've evaluated.
If you get a zero-length string, that just means that the result of the expression has that value. That could be an empty string, or an empty node-set.
The API docs for XPathEvaluator::evaluate() just say that it returns the result of the search. To find out exactly what that is, I dug through the XPathEvaluator::evaluate() code as far as I could but I got lost in all the cases in XPath::executeMore(). Searched the archive but didn't find anything.
The result of an XPath 1.0 expression can have a type of string, number, boolean or node-set. I'm assuming most of your expressions are location paths, so those will be of type node-set. In that case, you can call XObject::nodeset(), to get a reference to the underlying NodeRefListBase instance. However, if the expression is not a node-set, then calling that function will result in an exception. If you're worried about the type of the resulting XObject instance, you can call XObject::getType()
Q: which test should I use for an unsuccessful match, null or zero length, or could I get both and they mean different things?
You call nodeset() to get a reference to the underlying NodeRefListBase, then call getLength() to see how many nodes there are.
Dave
