Search Postgresql Archives

Re: Postgresql 8.4, XPath and name() function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 14/07/2010 12:09 AM, Tim Landscheidt wrote:
ced45<cedric.duprez@xxxxxx>  wrote:

I have trouble using XPath name() function in a XML field.
For example, when I execute the following query :

SELECT XPATH('name(/*)', XMLPARSE(DOCUMENT '<unit>value</unit>'))

It seems very odd that that returns an empty set. I'd expect that it should return "unit" if the xpath is being evaluated as an expression, or fail to compile if the xpath is being used as a selector.

In XSLT you couldn't use "name(/*)" as a selector in template match expression.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:template match="name(/*)">
  <xsl:element name="was-in-unit">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

$ xsltproc demo.xsl demo.xml
error
xsltCompileIdKeyPattern : expecting 'key' or 'id' or node type
compilation error: file demo.xsl line 5 element template
xsltCompilePattern : failed to compile 'name(/*)'


... but if "name(/*)" was evaluated as a value-expression it'd return "unit".

PostgreSQL's docs say:

"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."

http://developer.postgresql.org/pgdocs/postgres/functions-xml.html

and as the above xpath expression **should** return the node-set of a single text node with the value "unit", I'm a bit puzzled as to how Pg is getting an empty array.



I would like to get "unit", but I just get an empty array ({}).
How can I get "unit" ?

AFAIK, this is not related to PostgreSQL, but inherent to
XPath in that it returns elements from the document that
fulfill the XPath expression *unchanged*.

My (poor) understanding is that XPath can be used as an expression language and as a selector specifier language. You can observe this in XSLT, where

<xsl:template match="some-xpath"/>

uses XPath as a selector of elements, and:

<xsl:value-of select="some-xpath"/>

uses XPath as an expression language, returning the output of a given XPath expression or function not just the "matched"/"not matched" status.

I found this very confusing myself when learning XSLT, and it's possible I'm still misunderstanding it somewhat, but it's clear that XPath can be used in more than one way.


It seems that PostgreSQL is using it as a selector/specifier - ie "what matches this xpath". The OP wants to use it as an expression language, to get the result of the xpath expression not just the element it matches.

In the first use, as just a match expression, you'd see it applied like this:

demo.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:template match="/unit">                   <!-- selector -->
  <xsl:element name="was-in-unit">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

$ xsltproc demo.xsl demo.xml
<?xml version="1.0"?>
<was-in-unit>value</was-in-unit>


In the second use, like this:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:template match="/">
  <xsl:value-of select="name(/*)"/>             <!-- expression -->
</xsl:template>
</xsl:stylesheet>


$ xsltproc demo.xsl demo.xml
<?xml version="1.0"?>
unit







--
Craig Ringer

--
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux