Archetype
Archetype

Reputation: 307

Xpath substring-before gets only one element

<row transactionDateTime="2012-06-04 02:42:44" transactionID="2519826732" quantity="5000" typeName="Caldari Navy Mjolnir Rocket" typeID="27321" price="988.72" clientID="92026367" clientName="N Clover" stationID="60003760" stationName="Jita IV - Moon 4 - Caldari Navy Assembly Plant" transactionType="buy" transactionFor="personal" journalTransactionID="5956192510"/>

Hello,

Above is a sample of the XML file I am trying to extract data from. The piece of data I want to extract is;

transactionDateTime="2012-06-04"

Now - I am having no problems getting this with the following Xpath query;

substring-before(//row[@transactionfor='personal']/attribute::transactiondatetime, ' ')

This gets me exactly what I want - "2012-06-04", but it only gets me one element! If I drop the substring-before it will get me all elements, but include the time.

Any help would be great!

Upvotes: 3

Views: 8447

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243579

substring-before(//row[@transactionfor='personal']/attribute::transactiondatetime, ' ') 

In XPath 1.0 if a node-set is passed as argument where a single value (string) is expected, the first node in the node-set is used as the argument. The rule is to apply the function string() to the passed node-set and by definition string($nodeset) is the same as string($node-set[1]).

In XPath 2.0 the above expression should cause an error.

It isn't possible with a single XPath expression to produce the results of a function that is applied to all selected nodes, when the number of nodes is greater than 1.

Therefore, each selected node must be processed in a second step (probably in a loop specified in the programming language that is hosting XPath).

In XPath 2.0 it is possible to use a function call as the last location step of an expression.

Thus it is possible to produce a sequence of all wanted strings with this XPath 2.0 expression:

//row[@transactionfor='personal']
           /attribute::transactiondatetime
                           /substring-before(., ' ') 

Upvotes: 3

Daniel Haley
Daniel Haley

Reputation: 52888

It's not working because the first argument of substring-before() is a string and you're passing it the transactionDateTime attributes of all the rows.

Try this instead:

//row[@transactionFor='personal']/substring-before(@transactionDateTime,' ')

Upvotes: 1

Related Questions