Thread: Вопрос по xpath
Добрый день... Возникли проблемы с 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
День добрый. Дело не в Постгресе, а в самом 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']]);
$$<?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
В сообщении от Четверг 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