Обсуждение: Postgresql 8.4, XPath and name() function
Hi List, 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>')) I would like to get "unit", but I just get an empty array ({}). How can I get "unit" ? Thanks in advance, Cedric -- View this message in context: http://old.nabble.com/Postgresql-8.4%2C-XPath-and-name%28%29-function-tp29147655p29147655.html Sent from the PostgreSQL - general mailing list archive at Nabble.com.
On 13 July 2010 09:03, ced45 <cedric.duprez@ifn.fr> wrote: > > Hi List, > > 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>')) > > I would like to get "unit", but I just get an empty array ({}). > How can I get "unit" ? > eneral@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-general > Have you tried: SELECT XPATH('fn:name(/*)', XMLPARSE(DOCUMENT '<unit>value</unit>')); Thom
Thom Brown wrote: > > Have you tried: > > SELECT XPATH('fn:name(/*)', XMLPARSE(DOCUMENT '<unit>value</unit>')); > > Thom > > Thanks for your help, but it gives the whole element and not only the markup name. Cedric -- View this message in context: http://old.nabble.com/Postgresql-8.4%2C-XPath-and-name%28%29-function-tp29147655p29148011.html Sent from the PostgreSQL - general mailing list archive at Nabble.com.
ced45 <cedric.duprez@ifn.fr> 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>')) > 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*. So you will probably have to tackle your problem from an- other angle. Tim
On 14/07/2010 12:09 AM, Tim Landscheidt wrote: > ced45<cedric.duprez@ifn.fr> 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
Craig Ringer <craig@postnewspapers.com.au> wrote: > [...] >>> 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. > [...] Okay, that's maybe due to my XML socialization: An XPath ex- pression to me has always been something you use in "xsl:template" and "xmllint --shell", as in "xsl:value-of" & Co. you have also access to other functions. It's even in the specification :-): | [...] The primary purpose | of XPath is to address parts of an XML [XML] document. [...] (from: <URI:http://www.w3.org/TR/xpath/>) Tim
On Tue, Jul 13, 2010 at 4:03 AM, ced45 <cedric.duprez@ifn.fr> wrote: > > Hi List, > > 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>')) > > I would like to get "unit", but I just get an empty array ({}). > How can I get "unit" ? postgres is slightly broken in this regard. here is some discussions and a (might not work anymore) patch to fix the behavior if you're feeling adventurous... http://www.mail-archive.com/pgsql-hackers@postgresql.org/msg143339.html here is a 'works for my cases but probably not all of yours' regex solution that I use sometimes: create or replace function xnode(_xml xml) returns text as $$ select substring($1::text from '^<([[:alnum:]]+).*>'); $$ language sql immutable; merlin