1

I have tried this

select xpath('name()', unnest(xpath('/foo/*', '<foo><bar>test</bar><zar>test1</zar></foo>')));

As suggested in other question here, but I just get two empty rows as response.

In addition I have tried

select unnest(xpath('name(/foo/*)', '<foo><bar>test</bar><zar>test1</zar></foo>'));

But it returns only one row with response as bar.

Is there anyway I could get the query to return two rows with result bar, zar using Xpath?

3 Answers 3

2

I find xmltable() easier to work with if the output should be rows:

with data (content) as (
  values ('<foo><bar>test</bar><zar>test1</zar></foo>'::xml)
)  
select x.*
from data
  cross join xmltable('/foo/*' passing content
                       columns 
                         item text path 'name()', 
                         value text path '.') as x

Output is:

item | value
-----+------
bar  | test 
zar  | test1
Sign up to request clarification or add additional context in comments.

2 Comments

Is there anyway to get it only using Xpath? I would like to write index on xml document and I would like to index all the children under the element foo. Not sure if it somehow possible to index using xmltable.
@bharathp: no, that's not possible with xmltable. But you can't really create an index that would support the unnest() call result either.
1

Use the xpath function text() to extract the elements' contents:

SELECT unnest(xpath('/foo/*/text()','<foo><bar>test</bar><zar>test1</zar></foo>'));

 unnest 
--------
 test
 test1
(2 Zeilen)

To list the element names either use a subquery / CTE or use two unnest(), e.g.

SELECT 
  unnest(xpath('local-name(./*)',
  unnest(xpath('/foo/node()', '<foo><bar>test</bar><zar>test1</zar></foo>'))));

 unnest 
--------
 bar
 zar
(2 Zeilen)

2 Comments

I would like to get the element name, not the text in the element.
@bharathp I see.. can you try my last edit?
1

You can use the name() function to extract the tag name:

select xpath('name(/*)', x)
FROM unnest(
        xpath(
           '/foo/*',
           '<foo><bar>test</bar><zar>test1</zar></foo>'
        )
     ) AS xml(x);

 xpath 
═══════
 {bar}
 {zar}
(2 rows)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.