Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » How to check if XPath query returns empty result?
How to check if XPath query returns empty result? [message #52156] Fri, 17 October 2008 15:08 Go to next message
Jochen Wuttke is currently offline Jochen WuttkeFriend
Messages: 41
Registered: July 2009
Member
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 18:06 Go to previous messageGo to next message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
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 #52535 is a reply to message #52235] Wed, 29 October 2008 09:01 Go to previous messageGo to next message
Jochen Wuttke is currently offline Jochen WuttkeFriend
Messages: 41
Registered: July 2009
Member
Paul Elder wrote:
> 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.

Thanks, that all worked fine. But this raises a question that I couldn't
really answer when reading the XPAth spec: Does every XPath query always
return a node-set? Or are there other queries that directly return
"values" of some types?

Thanks,
Jochen
Re: How to check if XPath query returns empty result? [message #52561 is a reply to message #52535] Wed, 29 October 2008 12:12 Go to previous message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
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
Previous Topic:When will an Tag-Action be executed
Next Topic:AssertionFailed Exception with templates containing scriptles
Goto Forum:
  


Current Time: Sat Dec 20 11:41:10 GMT 2014

Powered by FUDForum. Page generated in 0.01992 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software