tags:

views:

67

answers:

3

hi everyone i have the following xml file

<author>
<firstname>Akhilesh</firstname>
<lastname>Singh</lastname>
</author>
<author>
<firstname>Prassana</firstname>
<lastname>Nagaraj</lastname>
</author>

and i am using the following jxpath expression

concat(author/firstName," ",author/lastName)

to get the value Akhilesh Singh ,Prassana Nagaraj but i am getting only Akhilesh Singh.My requirement is that i should get the value of both author by executing only one JXPath expression .Thanks in advance

A: 

concat() will return single string. If you want both results then you need to iterate over "author" element and do "concat(firstName," ",lastName)"

YoK
I have tried that but its not working
Akhilesh Kumar singh
@Akhilesh Kumar singh Can you share code how you did it ?
YoK
+1  A: 

With XPath 1.0, when an argument type other than node set is expected, the first node in the node set is selected and then apply the type conversion (boolean type conversion is some how different).

So, your expresion (Note: no capital):

concat(author/firstname," ",author/lastname) 

It's the same as:

concat( string( (author/firstname)[1] ), " ", string( (author/lastname)[1] ) ) 

Depending on the host language you could use:

author/firstname|author/lastname

This is evaluate to a node set with firstName and lastName in document order, so then you could iterate over this node set extracting the string value.

In XPath 2.0 you could use:

string-join(author/concat(firstname,' ', lastname),' ,')

Output:

Akhilesh Singh ,Prassana Nagaraj

Note: Now, with sequence data type and function calls as steps, XPath resembles the functional language it claims to be. Higher Order Functions and partial applycation must wait to XPath 2.1 ...

Edit: Thanks to Dimitre's comments, I've corrected the string separator.

Alejandro
+1 for the good explanation.
Dimitre Novatchev
See my answer for a better XPath 2.0 one-liner. :)
Dimitre Novatchev
The XPath 2.0 expression constructs a string that ends with " ,", but the OP doesn't want a trailing comma.
Dimitre Novatchev
@Dimitre: But there is no trailing separator with `fn:string-join`, by definition. Also tested in Saxon and Altova.
Alejandro
OK, I'm somewhat abset-minded today -- you still need to change '[space],' to ',[space]' :)
Dimitre Novatchev
"|" gives the output in mismatch format and other expressions are not working
Akhilesh Kumar singh
@Akhilesh Kumar singh: Did you read the explanation? Also, did you take notice wich expressions are XPath 1.0 and wich ones are XPath 2.0? Also, when someone post an "Output" in answer, it means that it has been tested. I guess you have no access to XPath 2.0 (rare, did you try Saxon?), so you only have the union expression that it gets evaluete to a node set (not a string like your concat). Take care in casting this result so you don't get a mismatch format.
Alejandro
+3  A: 

XPath 2.0 solution:

/*/author/concat(firstname, ' ', lastname, following-sibling::author/string(', '))
Dimitre Novatchev
@Dimitre: Yes, adding a `', '` only if there is a following sibling `author`. But, Do you think this has better performance than `fn:string-join`?
Alejandro
@Alejandro: before asking about performance, take care to correct your answer -- the OP wants *comma-delimited*, not *NL-delimited* names. The tricky part here is not to have the comma after the last name.
Dimitre Novatchev
@Dimitre: +1 Twice. You are right! Now you mention, I see the comma.
Alejandro
sorry the expression is not working
Akhilesh Kumar singh
@Akhilesh-Kumar-singh: I always test my answers. This expression has been verified to produce the correct result -- with Saxon9.1.07 and AltovaXML. You probably are using an XPath 1.0 engine, not an XPath 2.0 one.
Dimitre Novatchev