Is XPath sum or fn:sum function implemented in Pos

2019-07-03 02:10发布

问题:

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

回答1:

xpath does not create new nodes, it only filters the currently existing ones. That's what XSLT is for.

From the docs:

The function xpath evaluates the XPath expression xpath against the XML value xml. It returns an array of XML values corresponding to the node set produced by the XPath expression.

Since your XPath expression does not return a node set, there are not values in it and there is nothing to return.



回答2:

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)