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 that
it 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