Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is XPath sum or fn:sum function implemented in PostgreSQL XPath?

I'm using PostgreSQL 8.4 XPath (XML functions) feature. This is an adapted example found in docs:

SELECT xpath('/my:a/value[.>15]',
'<my:a xmlns:my="http://example.com">
<value>20</value>
<value>10</value>
<value>30</value>
</my:a>',
ARRAY[ARRAY['my', 'http://example.com']]);

This works fine, it returns a list of nodes correctly filtered with "value>15" condition:

xpath  
xml[]  
---------------------------------------  
"{<value>20</value>,<value>30</value>}"

But when I try to use "sum" it returns an empty list instead of a scalar value:

SELECT xpath('sum(/my:a/value[.>15])',  
...

result:

xpath  
xml[]  
-----  
"{}"

Any suggestions?

Juan Ferreyra

like image 749
Juan Ferreyra Avatar asked Jan 30 '26 19:01

Juan Ferreyra


1 Answers

I stumbled across the same problem and I am pleased to add another answer to the question:

With PostgreSQL 9.2 the documentation suddenly has one more sentence covering the xpath function:

If the XPath expression returns a scalar value rather than a node set, a single-element array is returned.

Just what I need! So in relation to the question another valid answer is: Upgrade to PostgreSQL 9.2. In the moment of writing this, version 9.2 is just a beta, but I can confirm that this works:

Version details

postgres=# select version();
                                                     version                                                      
------------------------------------------------------------------------------------------------------------------
 PostgreSQL 9.2beta1 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52), 64-bit
(1 row)

Demonstration of solution

(This demonstration was made with Postgre 9.5, because originally I pasted the wrong code)

postgres=# SELECT xpath('sum(/my:a/value[.>15])', '<my:a xmlns:my="http://example.com">
postgres'# <value>20</value>
postgres'# <value>10</value>
postgres'# <value>30</value>
postgres'# </my:a>',
postgres(# ARRAY[ARRAY['my', 'http://example.com']]);
 xpath 
-------
 {50}
(1 row)
like image 89
yankee Avatar answered Feb 03 '26 10:02

yankee



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!