2

On PostgreSQL 9.1 i can execute this two queries with out any errors, with correct result:

SELECT xpath('/a', '<a s:dd="11"><c>test</c></a>')
SELECT xpath('/a', '<a s:dd="11"><c>test</c></a>',ARRAY[ARRAY['s', 'http://example.com']])

On PostgreSQL 9.2 same queries throws error:

ERROR:  could not parse XML document
DETAIL:  line 1: Namespace prefix s for dd on a is not defined

Only this query works fine:

SELECT xpath('/a', '<a xmlns:s="ddd" s:dd="11"><c>test</c></a>')

How can i parse XML file, whth out modifying XML code?

Problems starts when i want to make xpath query for xml element, recived from previous query.

For example xml document:

 <some xmlns:my="somens">
      <a>
          <b my:param="11" />
      </a>
 </some>

And i want to do something like this:

 elem = xpath('/a',doc);
 elem2= xpath('//b',elem[0]);

And second row throws error, becouse of unknown prefix my. Any ideas?

1
  • did you try my suggestion? Commented Jan 5, 2013 at 10:39

1 Answer 1

1

I fail to see the problem you're having other than PostgreSQL breaking features. In the first document

This is the expected behavior from a strict XML parser. The fact that PostgreSQL changed behavior is bad, but something we just have to deal with I guess.

This

SELECT xpath('/a', '<a s:dd="11"><c>test</c></a>')

fails because the s namespace is not declared in the XML document. This works:

# SELECT xpath('/a', '<a xmlns:s="http://example.com" s:dd="11"><c>..</c></a>');
                      xpath                       
--------------------------------------------------
 {"<a xmlns:s=\"http://example.com\" s:dd=\"11\">+
   <c>..</c>                                   +
 </a>"}
(1 row)

What you're doing here:

SELECT xpath('/a', '<a xmlns:s="http://example.com" s:dd="11"><c>..</c></a>',
    ARRAY[ARRAY['s', 'http://example.com']]);

is to bind the s namespace to http://example.com enabling you to run xpath expressions in that namespace. Observe:

This is the original query but where the a tag is in the http://example.com namespace. Your query (/a) doesn't match any document as you're querying for a elements in the default namespace:

# SELECT xpath('/a', '<s:a xmlns:s="http://example.com" s:dd="11"><c>test</c></s:a>');
 xpath 
-------
 {}
(1 row)

This however, selects the root element:

# SELECT xpath('/x:a', '<s:a xmlns:s="http://example.com" s:dd="11"><c>..</c></s:a>',
    ARRAY[ARRAY['x', 'http://example.com']]);
                       xpath                        
----------------------------------------------------
 {"<s:a xmlns:s=\"http://example.com\" s:dd=\"11\">+
   <c>test</c>                                     +
 </s:a>"}
(1 row)

Notice how s and x are bound to the same namespace http://example.com. Using different namespace bindings is confusing, but I just wanted to show you how it works.

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

2 Comments

Sory, it's holidays in russia, until 9th january. I'll try, when i'll return to office, and write a response here.
Ah, no problem. Just wondering if was correct/helpful as I'm new to postgresql and xml myself.

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.