| 
| 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.04163 seconds