0

I'm trying to extract values from XML stored in the PostgreSQL DB using XPath. I've got an error:

SQL Error [42601]: ERROR: syntax error at or near "["

My SQL is:

-- Find "e" nodes which have "p1" child nodes and does not have "p3" child nodes
WITH tbl(p_xml) AS (
   SELECT '<root>
    <e id="1">
        <p1>P1</p1>
        <p2>P2</p2>
    </e>
    <e id="2">
        <p1>P1</p1>
        <p3>P2</p3>
    </e>
    <e id="3">
        <p2>P1</p2>
        <p3>P3</p3>
    </e>
</root>'::xml
)
select * 
FROM   tbl
where
    (xpath('count(/root/e/p1)', p_xml)[1]::text)::int > 0 and 
    (xpath('count(/root/e/p3)', p_xml)[1]::text)::int = 0

I've seen plenty of examples on StackOverflow with using squares to get data (as xpath function returns array), but all of them fails with the same error on my PostgreSQL. I tried this on PostgreSQL DB versions 9.6 and 10.1 with no luck.

2 Answers 2

3

That's because your query lacks a brackets. Anyways, if you want to return just e elements that fulfill that condition you'll need to shred the XML, for example :

WITH tbl(p_xml) AS (
   SELECT '<root>
    <e id="1">
        <p1>P1</p1>
        <p2>P2</p2>
    </e>
    <e id="2">
        <p1>P1</p1>
        <p3>P2</p3>
    </e>
    <e id="3">
        <p2>P1</p2>
        <p3>P3</p3>
    </e>
</root>'::xml
)
SELECT e
FROM tbl
CROSS JOIN LATERAL UNNEST(xpath('//e[p1 and not(p3)]', p_xml)) e

rextester demo: http://rextester.com/FZGP41665

Sign up to request clarification or add additional context in comments.

1 Comment

I knew, there must be a better approach :-)
1

I'm not experienced with postgresql, but this seems to work:

where
    (xpath('count(/root/e/p1)', p_xml)::text[])[1]::int > 0 and 
    (xpath('count(/root/e/p3)', p_xml)::text[])[1]::int = 0

It looks, as if xpath() must be casted to an array of string, where you pick the first element to cast it to int. Not very intuitive.

There might be a better approach...

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.