Skip to content
Advertisement

PostgreSQL11 xpath query not working properly

When I execute below query in Postgres 10.12, it works properly.

SELECT (xpath('./sid/text()', c.node))[1]::text::bigint AS STUDENT_ID,
       (xpath('./name/text()', c.node))[1]::text AS STUDENT_NAME
from (    
  select unnest(xpath('/data', '<data><sid>112233</sid><name>John</name></data>'::xml)) AS node    
) c;

Output:

enter image description here

But When I execute same query in Postgres 11.7, it is not working.

enter image description here

What is the solution to fix this issue?

Advertisement

Answer

This is caused by this change:

Correctly handle relative path expressions in xmltable(), xpath(), and other XML-handling functions (Markus Winand)

Per the SQL standard, relative paths start from the document node of the XML input document, not the root node as these functions previously did.

so you need to change it to:

SELECT (xpath('/data/sid/text()', c.node))[1]::text::bigint AS STUDENT_ID,
       (xpath('/data/name/text()', c.node))[1]::text AS STUDENT_NAME
from (    
  select unnest(xpath('/data', '<data><sid>112233</sid><name>John</name></data>'::xml)) AS node    
) c;

because the inner xpath will return the <data> tag as well:

select unnest(xpath('/data', '<data><sid>112233</sid><name>John</name></data>'::xml)) AS node

results in:

<data>
  <sid>112233</sid>
  <name>John</name>
</data>


However, I would use xmltable for this:

select *
from xmltable('/data'
               passing xml('<data><sid>112233</sid><name>John</name></data>')
               columns 
                  student_id bigint path 'sid', 
                  student_name text path 'name')

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement