Обсуждение: Вопрос по xpath

Поиск
Список
Период
Сортировка

Вопрос по xpath

От
"Denis I. Polukarov"
Дата:
Добрый день...

 Возникли проблемы с xpath, в решении которых ни google, ни документация по
postgresql ответов не дали...

Поля без namespace не ищет:

test=# SELECT xpath('//qDate/text()',
                                                                                                           
$$<?xml version='1.0' encoding='UTF-8'?>
                                                                                                                    
<epp xmlns='urn:ietf:params:xml:ns:epp-1.0'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd'><response><result code='1301'><msg lang='en-US'>Command completed
successfully; ack to dequeue</msg></result><msgQ count='3'
id='114004'><qDate>2010-06-02T12:35:33.0Z</qDate><msg lang='en-US'>Transfer
Requested.</msg></msgQ><resData><domain:trnData
xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'
xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0

domain-1.0.xsd'><domain:name>xxx.xx</domain:name><domain:trStatus>pending</domain:trStatus><domain:reID>admin</domain:reID><domain:reDate>2010-06-02T12:35:33.0Z</domain:reDate><domain:acID>xxx-

xx</domain:acID><domain:acDate>2010-06-07T12:35:33.0Z</domain:acDate><domain:exDate>2014-05-11T12:52:07.0Z</domain:exDate></domain:trnData></resData><trID><svTRID>xx-
xxx</svTRID></trID></response></epp>$$);
 xpath
-------
 {}
(1 row)

test=#

С namespace ищет:

test=# SELECT xpath('//domain:name/text()',
$$<?xml version='1.0' encoding='UTF-8'?>
                                                                                                                    
<epp xmlns='urn:ietf:params:xml:ns:epp-1.0'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd'><response><result code='1301'><msg lang='en-US'>Command completed
successfully; ack to dequeue</msg></result><msgQ count='3'
id='114004'><qDate>2010-06-02T12:35:33.0Z</qDate><msg lang='en-US'>Transfer
Requested.</msg></msgQ><resData><domain:trnData
xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'
xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0

domain-1.0.xsd'><domain:name>xxx.xx</domain:name><domain:trStatus>pending</domain:trStatus><domain:reID>admin</domain:reID><domain:reDate>2010-06-02T12:35:33.0Z</domain:reDate><domain:acID>xxx-

xx</domain:acID><domain:acDate>2010-06-07T12:35:33.0Z</domain:acDate><domain:exDate>2014-05-11T12:52:07.0Z</domain:exDate></domain:trnData></resData><trID><svTRID>xx-
xxx</svTRID></trID></response></epp>$$,
array[array['domain','urn:ietf:params:xml:ns:domain-1.0']]);
    xpath
-------------
 {xxx.xx}
(1 row)

test=#

Почему не ищет поле без namespace?

--
Best regards,
Denis I. Polukarov

Re: [pgsql-ru-general] Вопрос по xpath

От
Nikolay Samokhvalov
Дата:
День добрый. Дело не в Постгресе, а в самом XML и том, как с ним работают с помощью библиотеки libxml.

У вас в документе нет "голого" элемента qDate. Есть элемент под неймспейсом.

Обратите внимание:
  "<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' ....> -- тут указывается "дефолтовый" неймспейс для "внутренностей" элемента epp. Это неймспейс 'urn:ietf:params:xml:ns:epp-1.0'. Чтобы работать с неймспейсами, им надо давать алиасы. Внутри XML-документа алиасы тоже раздаются, но не всегда, иногда бывают вот такие, "дефолтовые". Постгрес, как и библиотека libxml, для оценки XPath-выражений работает только через алиасы.

Так что вам надо "регистрировать" дефолтовый неймспейс (т.е. давать алиас), как и любой другой. Алиас ему можете придумать произвольное. Например, "lalala".  Делается это в с помощью двумерного массива, точно так же, как в вашем втором примере.

Дальше ко всем элементам внутри элемента <epp>, которые "как бы без неймспейса" (хотя в реальности они все ходят под этим самым дефолтовым) обращаться надо через свой алиас -- т.е. в вашем примере '//lalala:qDate/text()'.

Для бОльшего понимания: во втором, как бы правильно работающем вашем примере вы запросто могли бы использовать в качестве алиаса не 'domain', а 'chtougodno':

SELECT xpath('//chtougodno:name/text()',
$$<?xml version='1.0' encoding='UTF-8'?>
<epp ...>...</epp>$$,
array[array['chtougodno','urn:ietf:params:xml:ns:domain-1.0']]); 

-- такое тоже должно работать.

Надеюсь, понятно. У меня к вам просьба -- если знаете английский, внесите в pgsql-hackers предложение по добавлению этого нюанса в документацию.

On Thu, Jun 3, 2010 at 12:10, Denis I. Polukarov <d.polukarov@gpt.ru> wrote:
 Добрый день...

 Возникли проблемы с xpath, в решении которых ни google, ни документация по
postgresql ответов не дали...

Поля без namespace не ищет:

test=# SELECT xpath('//qDate/text()',
$$<?xml version='1.0' encoding='UTF-8'?>
<epp xmlns='urn:ietf:params:xml:ns:epp-1.0'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd'><response><result code='1301'><msg lang='en-US'>Command completed
successfully; ack to dequeue</msg></result><msgQ count='3'
id='114004'><qDate>2010-06-02T12:35:33.0Z</qDate><msg lang='en-US'>Transfer
Requested.</msg></msgQ><resData><domain:trnData
xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'
xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0
domain-1.0.xsd'><domain:name>xxx.xx</domain:name><domain:trStatus>pending</domain:trStatus><domain:reID>admin</domain:reID><domain:reDate>2010-06-02T12:35:33.0Z</domain:reDate><domain:acID>xxx-
xx</domain:acID><domain:acDate>2010-06-07T12:35:33.0Z</domain:acDate><domain:exDate>2014-05-11T12:52:07.0Z</domain:exDate></domain:trnData></resData><trID><svTRID>xx-
xxx</svTRID></trID></response></epp>$$);
 xpath
-------
 {}
(1 row)

test=#

С namespace ищет:

test=# SELECT xpath('//domain:name/text()',
$$<?xml version='1.0' encoding='UTF-8'?>
<epp xmlns='urn:ietf:params:xml:ns:epp-1.0'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd'><response><result code='1301'><msg lang='en-US'>Command completed
successfully; ack to dequeue</msg></result><msgQ count='3'
id='114004'><qDate>2010-06-02T12:35:33.0Z</qDate><msg lang='en-US'>Transfer
Requested.</msg></msgQ><resData><domain:trnData
xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'
xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0
domain-1.0.xsd'><domain:name>xxx.xx</domain:name><domain:trStatus>pending</domain:trStatus><domain:reID>admin</domain:reID><domain:reDate>2010-06-02T12:35:33.0Z</domain:reDate><domain:acID>xxx-
xx</domain:acID><domain:acDate>2010-06-07T12:35:33.0Z</domain:acDate><domain:exDate>2014-05-11T12:52:07.0Z</domain:exDate></domain:trnData></resData><trID><svTRID>xx-
xxx</svTRID></trID></response></epp>$$,
array[array['domain','urn:ietf:params:xml:ns:domain-1.0']]);
   xpath
-------------
 {xxx.xx}
(1 row)

test=#

Почему не ищет поле без namespace?

--
Best regards,
Denis I. Polukarov

--
Sent via pgsql-ru-general mailing list (pgsql-ru-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-ru-general

Re: Re: [pgsql-ru-general] Вопрос по xpath

От
"Denis I. Polukarov"
Дата:
В сообщении от Четверг 03 июня 2010 14:21:00 автор Nikolay Samokhvalov
написал:
> День добрый. Дело не в Постгресе, а в самом XML и том, как с ним работают с
> помощью библиотеки libxml.
>
> У вас в документе нет "голого" элемента qDate. Есть элемент под
> неймспейсом.
>
> Обратите внимание:
>   "<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' ....> -- тут указывается
> "дефолтовый" неймспейс для "внутренностей" элемента epp. Это неймспейс
> 'urn:ietf:params:xml:ns:epp-1.0'.
> Чтобы работать с неймспейсами, им надо давать алиасы. Внутри XML-документа
> алиасы тоже раздаются, но не всегда, иногда бывают вот такие, "дефолтовые".
> Постгрес, как и библиотека libxml, для оценки XPath-выражений работает
> только через алиасы.
>
> Так что вам надо "регистрировать" дефолтовый неймспейс (т.е. давать алиас),
> как и любой другой. Алиас ему можете придумать произвольное. Например,
> "lalala".  Делается это в с помощью двумерного массива, точно так же, как в
> вашем втором примере.
>
> Дальше ко всем элементам внутри элемента <epp>, которые "как бы без
> неймспейса" (хотя в реальности они все ходят под этим самым дефолтовым)
> обращаться надо через свой алиас -- т.е. в вашем примере
> '//lalala:qDate/text()'.
>
> Для бОльшего понимания: во втором, как бы правильно работающем вашем
> примере вы запросто могли бы использовать в качестве алиаса не 'domain', а
> 'chtougodno':
>
> SELECT xpath('//chtougodno:name/text()',
> $$<?xml version='1.0' encoding='UTF-8'?>
> <epp ...>...</epp>$$,
> array[array['chtougodno','urn:ietf:params:xml:ns:domain-1.0']]);
>
> -- такое тоже должно работать.
>
> Надеюсь, понятно. У меня к вам просьба -- если знаете английский, внесите в
> pgsql-hackers предложение по добавлению этого нюанса в документацию.

...запостил.

>
> On Thu, Jun 3, 2010 at 12:10, Denis I. Polukarov <d.polukarov@gpt.ru> wrote:
> >  Добрый день...
> >
> >  Возникли проблемы с xpath, в решении которых ни google, ни документация
> >  по
> >
> > postgresql ответов не дали...
> >
> > Поля без namespace не ищет:
> >
> > test=# SELECT xpath('//qDate/text()',
> > $$<?xml version='1.0' encoding='UTF-8'?>
> > <epp xmlns='urn:ietf:params:xml:ns:epp-1.0'
> > xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
> > xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0
> > epp-1.0.xsd'><response><result code='1301'><msg lang='en-US'>Command
> > completed
> > successfully; ack to dequeue</msg></result><msgQ count='3'
> > id='114004'><qDate>2010-06-02T12:35:33.0Z</qDate><msg
> > lang='en-US'>Transfer Requested.</msg></msgQ><resData><domain:trnData
> > xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'
> > xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0
> >
> > domain-1.0.xsd'><domain:name>xxx.xx</domain:name><domain:trStatus>pending
> > </domain:trStatus><domain:reID>admin</domain:reID><domain:reDate>2010-06-
> > 02T12:35:33.0Z</domain:reDate><domain:acID>xxx-
> >
> > xx</domain:acID><domain:acDate>2010-06-07T12:35:33.0Z</domain:acDate><dom
> > ain:exDate>2014-05-11T12:52:07.0Z</domain:exDate></domain:trnData></resDa
> > ta><trID><svTRID>xx- xxx</svTRID></trID></response></epp>$$);
> >
> >  xpath
> >
> > -------
> >
> >  {}
> >
> > (1 row)
> >
> > test=#
> >
> > С namespace ищет:
> >
> > test=# SELECT xpath('//domain:name/text()',
> > $$<?xml version='1.0' encoding='UTF-8'?>
> > <epp xmlns='urn:ietf:params:xml:ns:epp-1.0'
> > xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
> > xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0
> > epp-1.0.xsd'><response><result code='1301'><msg lang='en-US'>Command
> > completed
> > successfully; ack to dequeue</msg></result><msgQ count='3'
> > id='114004'><qDate>2010-06-02T12:35:33.0Z</qDate><msg
> > lang='en-US'>Transfer Requested.</msg></msgQ><resData><domain:trnData
> > xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'
> > xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0
> >
> > domain-1.0.xsd'><domain:name>xxx.xx</domain:name><domain:trStatus>pending
> > </domain:trStatus><domain:reID>admin</domain:reID><domain:reDate>2010-06-
> > 02T12:35:33.0Z</domain:reDate><domain:acID>xxx-
> >
> > xx</domain:acID><domain:acDate>2010-06-07T12:35:33.0Z</domain:acDate><dom
> > ain:exDate>2014-05-11T12:52:07.0Z</domain:exDate></domain:trnData></resDa
> > ta><trID><svTRID>xx- xxx</svTRID></trID></response></epp>$$,
> > array[array['domain','urn:ietf:params:xml:ns:domain-1.0']]);
> >
> >    xpath
> >
> > -------------
> >
> >  {xxx.xx}
> >
> > (1 row)
> >
> > test=#
> >
> > Почему не ищет поле без namespace?
> >
> > --
> > Best regards,
> > Denis I. Polukarov
> >
> > --
> > Sent via pgsql-ru-general mailing list (pgsql-ru-general@postgresql.org)
> > To make changes to your subscription:
> > http://www.postgresql.org/mailpref/pgsql-ru-general

--
Best regards,
Denis I. Polukarov
developer
"Garant-Park-Telekom"
http://www.gpt.ru