How to check if XPath query returns empty result? [message #52156] |
Fri, 17 October 2008 11:08  |
Eclipse User |
|
|
|
In my transformation I have case where I have to generate different code
depending on the value of an optional attribute in my XML file. So when
I select the attribute via
<c:setVariable select="/path/to/object@attribute" var="myAttribute"/>
the variable "myAttribute" may be empty after that call. What I'd like
to do now is to use c:if something like this:
<c:if test="$myAttribute = ''">
do something
</c:if>
But somehow I can't get this test to work properly.
I tried the following test expressions:
$myAttribute = ""
$myAttribute = string("")
string-length($myAttribute) = 0
string($myAttribute) = ""
None of them ever returns true, even in the cases where the variable
value is "empty", i.e. when in the generated code nothing appears in
place of the variable.
What am I missing? This must be something fairly common to do, or not?
Jochen
|
|
|
Re: How to check if XPath query returns empty result? [message #52235 is a reply to message #52156] |
Mon, 20 October 2008 14:06   |
Eclipse User |
|
|
|
Jochen:
First, a small syntax correction. I assume you mean:
<c:setVariable select="/path/to/object/@attribute" var="myAttribute"/>
(I added a slash before the @ - otherwise, you should get a syntax error)
Anyhow, myAttribute will be set to a 'nodeSet' containing all attribute
nodes that match your select expression.
So, to test whether you got anything at all:
<c:if test="count($myAttribute) = 0" >
<%-- nothing matched --%>
</c:if>
You can use this equivalent short-hand:
<c:if test="$myAttribute" >
This reliese on the definition of the boolean function
(http://www.w3.org/TR/xpath#function-boolean), which converts a Node-set
($myAttribute) into a boolean based on whether it has any members or not.
But, XPaths auto-casting between node-sets, strings and booleans gets in
the way of tests for zero-length strings. The auto-casting generally reults
in missing attributes and zero-length attributes being treated as
equivalent. For example, in
<c:if test="$myAttribute = '' >
is equivalent to
<c:if test="string($myAttribute) = '' " >
And, if you look up http://www.w3.org/TR/xpath#function-string, you'll see
that an empty node-set gets converted into the zero-length string, so this
test will not distinguish between finding no attribute, and finding an
attribute with a zero-length value. To find a zero-length attribute, you
need to do:
<c:if test="count($myAttribute) = 1 and string($myAttribute) = '' ">
or more simply:
<c:if test="$myAttribute and $myAttribute = '' ">
FYI, another area where XPath gets a little counter-intuitive is in dealling
with strings containing works like 'true' and 'false'. The expression:
The expression:
string(1 = 1)
returns the string 'true'
But:
boolean(string(1 = 1))
returns a boolean false value, because boolean converts strings to booleans
by counting characters, not by looking at the contents.
Paul
|
|
|
|
Re: How to check if XPath query returns empty result? [message #52561 is a reply to message #52535] |
Wed, 29 October 2008 08:12  |
Eclipse User |
|
|
|
Jochen:
Some XPath queries return literals: String, Boolean or Number. But
expressions that access attributes or elements always return node sets:
Some examples:
count(/path/to/object/@attribute) - returns a Number
/path/to/object/@attribute - returns a node set (even if only one attribute
is matched)
string(/path/to/object/@attribute) - returns a String
/path/to/object/@attribute = /path/to/object/@another - returns Boolean
/path/to/object[1] - returns a node set (even though it contains only one
object)
And, you're not alone in finding the XPath 1.0 spec vague at times :-)
Paul
|
|
|
Powered by
FUDForum. Page generated in 0.07462 seconds