Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как проверить, что в поле - XML? / 22 сообщений из 22, страница 1 из 1
30.07.2021, 06:47
    #40087212
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Народ, всем привет!
И вроде простой вопрос, но найти ответ пока не смог. Может и плохо искал, конечно...
Но всё же, как сделать так, чтобы данный запрос выполнился, вернув одну строку, с корректным XML?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
with xml_test(ex_xml, xml_validation) as (
select
'<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>' , 'true' from dual

union select 
'<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>
<Bug>
</Bug>', 'false' from dual)
select xmltype(ex_xml), xml_validation from xml_test



В данном примере мы не проверяем соответствие структуры схеме XSD, а проверяем просто синтаксис. Т.е. нужно выбрать строки, которые может переварить xmltype().
Может быть есть какой-то простой способ для этого?
...
Рейтинг: 0 / 0
30.07.2021, 07:57
    #40087217
123йй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
...
Рейтинг: 0 / 0
30.07.2021, 09:21
    #40087239
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?

Спасибо, но это не то. XMLType.isSchemaValid проверяет уже корректный (синтаксически) XML на соответствие XSD-схеме. А мне нужно проверить, что в поле находится корректный XML, с корректным синтаксисом, без нескольких корней итд. Это немного другая задача.
Можно конечно запилить функцию, которая будет строку передавать в XMLType() и обрабатывать исключения, но какой-то это кривой способ, наверняка есть что-то штатное для этого.
...
Рейтинг: 0 / 0
30.07.2021, 09:44
    #40087249
Алымов Анатолий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Synoptic

Спасибо, но это не то. XMLType.isSchemaValid проверяет уже корректный (синтаксически) XML на соответствие XSD-схеме. А мне нужно проверить, что в поле находится корректный XML, с корректным синтаксисом, без нескольких корней итд. Это немного другая задача.
Можно конечно запилить функцию, которая будет строку передавать в XMLType() и обрабатывать исключения, но какой-то это кривой способ, наверняка есть что-то штатное для этого.

Стандартной не нашел. to_number c DEFAULT ON CONVERSION ERROR появилась только в 12.2, для xmltype ожидать этого не стоит. Может когда и добавят
...
Рейтинг: 0 / 0
30.07.2021, 10:56
    #40087262
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Алымов Анатолий

Стандартной не нашел. to_number c DEFAULT ON CONVERSION ERROR появилась только в 12.2, для xmltype ожидать этого не стоит. Может когда и добавят

Ну вот да. Была ещё мыль про VALIDATE_CONVERSION, но она не понимает xmltype
...
Рейтинг: 0 / 0
30.07.2021, 13:35
    #40087327
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Synoptic

В данном примере мы не проверяем соответствие структуры схеме XSD, а проверяем просто синтаксис. Т.е. нужно выбрать строки, которые может переварить xmltype().
Может быть есть какой-то простой способ для этого?


И что мешает написать функцию:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
create or replace
  function is_xml(
                  p_clob clob
                 )
    return varchar2
    is
        v_xml xmltype;
    begin
        v_xml := xmltype(p_clob);
        return 'true';
      exception
        when others
          then
            return 'false';
end;
/
with xml_test(ex_xml, xml_validation) as (
select
'<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>' , 'true' from dual
union select 
'<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>
<Bug>
</Bug>', 'false' from dual)
select  xmltype(ex_xml)
  from  xml_test
  where is_xml(ex_xml) = 'true'
/

XMLTYPE(EX_XML)
--------------------------------------------------------------------------------
<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>


SQL>



SY.
...
Рейтинг: 0 / 0
30.07.2021, 14:02
    #40087334
qlost
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Если xml-ка большая, можно заюзать SAX
...
Рейтинг: 0 / 0
30.07.2021, 14:13
    #40087335
Bsplesk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
del
...
Рейтинг: 0 / 0
30.07.2021, 20:24
    #40087428
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
SY

И что мешает написать функцию

Ничего, вопрос был про возможный штатный способ. Писал об этом:

Synoptic

Можно конечно запилить функцию, которая будет строку передавать в XMLType() и обрабатывать исключения, но какой-то это кривой способ, наверняка есть что-то штатное для этого.
...
Рейтинг: 0 / 0
30.07.2021, 20:55
    #40087430
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Synoptic

Ничего, вопрос был про возможный штатный способ. Писал об этом:


Если это ETL то можно создать exceptions table и залить в таблицу через INSERT EXCEPTIONS INTO.

SY.
...
Рейтинг: 0 / 0
31.07.2021, 10:15
    #40087463
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
SY

Если это ETL то можно создать exceptions table и залить в таблицу через INSERT EXCEPTIONS INTO.
SY.

Не, это обработчик данных, который пишет в логи в виде XML, но временами вместо XML там оказывается какая-то дичь.
В общем да, видимо проще всего через функцию.
Всем, спасибо!

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
with
  function is_xml(p_xml clob) return varchar2
  is v_xml xmltype;
  begin
    v_xml := xmltype(p_xml);
        return 'true';
      exception
        when others
          then
            return 'false'; 
  end;
  
xml_test(ex_xml, xml_validation) as (
select
'<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>' , 'true' from dual
union select 
'<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>
<Bug>
</Bug>', 'false' from dual)

select  ex_xml from xml_test 
    where 
      is_xml(ex_xml) = 'true';
...
Рейтинг: 0 / 0
31.07.2021, 10:18
    #40087465
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Synoptic,
Я бы из функции возвращал сам xmltype, чтобы дважды не конвертить.
И null в случае exception.
...
Рейтинг: 0 / 0
31.07.2021, 12:27
    #40087477
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Разумно!
...
Рейтинг: 0 / 0
31.07.2021, 18:49
    #40087534
qlost
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
.
...
Рейтинг: 0 / 0
31.07.2021, 19:16
    #40087536
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
andrey_anonymous
Synoptic,
Я бы из функции возвращал сам xmltype, чтобы дважды не конвертить.
И null в случае exception.


Согласен. Кстати конвертится один раз, хотя на больших CLOB не факт и не факт deterministic поможет.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> set serveroutput on
SQL> create or replace
  2    function is_xml(
  3                    p_clob clob
  4                   )
  5      return varchar2
  6      is
  7          v_xml xmltype;
  8      begin
  9          dbms_output.put_line('Fire!');
 10          v_xml := xmltype(p_clob);
 11          return 'true';
 12        exception
 13          when others
 14            then
 15              return 'false';
 16  end;
 17  /

Function created.

SQL> with xml_test(ex_xml, xml_validation) as (
  2  select
  3  '<Data>
  4    <EMPLOYER>
  5      <SUMMARY>
  6        <WORKER>
  7          <RESULT_DETAIL>
  8            <CLASS>z</CLASS>
  9          </RESULT_DETAIL>
 10        </WORKER>
 11      </SUMMARY>
 12    </EMPLOYER>
 13  </Data>' , 'true' from dual
 14  union select
 15  '<Data>
 16    <EMPLOYER>
 17      <SUMMARY>
 18        <WORKER>
 19          <RESULT_DETAIL>
 20            <CLASS>z</CLASS>
 21          </RESULT_DETAIL>
 22        </WORKER>
 23      </SUMMARY>
 24    </EMPLOYER>
 25  </Data>
 26  <Bug>
 27  </Bug>', 'false' from dual)
 28  select  xmltype(ex_xml)
 29    from  xml_test
 30    where is_xml(ex_xml) = 'true'
 31  /

XMLTYPE(EX_XML)
--------------------------------------------------------------------------------
<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>


Fire!
Fire!
SQL>



SY.
...
Рейтинг: 0 / 0
01.08.2021, 10:03
    #40087568
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
SY
andrey_anonymous
Synoptic,
Я бы из функции возвращал сам xmltype, чтобы дважды не конвертить.
И null в случае exception.


Согласен. Кстати конвертится один раз, хотя на больших CLOB не факт и не факт deterministic поможет.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> set serveroutput on
SQL> create or replace
  2    function is_xml(
  3                    p_clob clob
  4                   )
  5      return varchar2
  6      is
  7          v_xml xmltype;
  8      begin
  9          dbms_output.put_line('Fire!');
 10          v_xml := xmltype(p_clob);
 11          return 'true';
 12        exception
 13          when others
 14            then
 15              return 'false';
 16  end;
 17  /

Function created.

SQL> with xml_test(ex_xml, xml_validation) as (
  2  select
  3  '<Data>
  4    <EMPLOYER>
  5      <SUMMARY>
  6        <WORKER>
  7          <RESULT_DETAIL>
  8            <CLASS>z</CLASS>
  9          </RESULT_DETAIL>
 10        </WORKER>
 11      </SUMMARY>
 12    </EMPLOYER>
 13  </Data>' , 'true' from dual
 14  union select
 15  '<Data>
 16    <EMPLOYER>
 17      <SUMMARY>
 18        <WORKER>
 19          <RESULT_DETAIL>
 20            <CLASS>z</CLASS>
 21          </RESULT_DETAIL>
 22        </WORKER>
 23      </SUMMARY>
 24    </EMPLOYER>
 25  </Data>
 26  <Bug>
 27  </Bug>', 'false' from dual)
 28  select  xmltype(ex_xml)
 29    from  xml_test
 30    where is_xml(ex_xml) = 'true'
 31  /

XMLTYPE(EX_XML)
--------------------------------------------------------------------------------
<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>


Fire!
Fire!
SQL>



SY.

Андрей имел в виду, что дважды конвертится - это
Код: plsql
1.
2.
3.
 select  xmltype(ex_xml)
 29    from  xml_test
 30    where is_xml(ex_xml) = 'true'


лучше одним запросом
Код: plsql
1.
2.
 select  is_xml(ex_xml)
 from  xml_test

, где функция сразу возвращает xml или null
...
Рейтинг: 0 / 0
01.08.2021, 12:38
    #40087582
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
И никто так и не скажет, что у аффтара оба XML одинаково валидные/инвалидные с точки
зрения спецификации?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
03.08.2021, 13:02
    #40088181
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Dimitry Sibiryakov
И никто так и не скажет, что у аффтара оба XML одинаково валидные/инвалидные с точки
зрения спецификации?..

XML с двумя корнями валидна?
...
Рейтинг: 0 / 0
03.08.2021, 13:06
    #40088186
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
SynopticXML с двумя корнями валидна?

Корень XML это тэг <xml>. Он отсутствует в обоих вариантах. Да, в этом случае там могут
быть сколько угодно разных "корней".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
03.08.2021, 18:54
    #40088340
Synoptic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Dimitry Sibiryakov, хочешь сказать, что оракловый xmltype() работает некорректно?
...
Рейтинг: 0 / 0
03.08.2021, 19:05
    #40088350
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Да.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
04.08.2021, 01:03
    #40088456
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как проверить, что в поле - XML?
Synoptic
Dimitry Sibiryakov, хочешь сказать, что оракловый xmltype() работает некорректно?


Код: plsql
1.
2.
3.
4.
XMLType is a system-defined opaque type for handling XML data.
It as predefined member functions on it to extract XML nodes and fragments.
You can create columns of XMLType and insert XML documents into it. 
You can also generate XML documents as XMLType instances dynamically using the SYS_XMLGEN and SYS_XMLAGG SQL functions.



Однако в действительности это не просто XML document а single rooted XML document. Причем в SQL конструктор XMLTYPE не реагирует на параметр wellformed (Flag to indicate that the input is well formed. If set, then the database would not do well formed check on the input instance. Default is 0):

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select xmltype('<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>
<Bug>
  <ID>12345</ID>
</Bug>',wellformed=>1) from dual
/
ERROR:
OCI-31011: XML parsing failed

SQL>



А в PL/SQL (когда уж Oracle перейдет к single engine):


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
declare
    v_xml xmltype;
begin
    v_xml := xmltype('<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>
<Bug>
  <ID>12345</ID>
</Bug>',wellformed=>1);
end;


PL/SQL procedure successfully completed.

SQL>



Посему в таких как у тебя случаях лучше использовать XMLPARSE который принимает на вход как XML document так и content:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
with t as (
           select  xmlparse(content '<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>
<Bug>
  <ID>12345</ID>
</Bug>') x from dual
          )
select  class,
        id
  from  t,
        xmltable(
                 '/'
                 passing x
                 columns
                   class varchar2(10) path '/Data/EMPLOYER/SUMMARY/WORKER/RESULT_DETAIL/CLASS',
                   id number path '/Bug/ID'
                )
/

CLASS              ID
---------- ----------
z               12345

SQL>



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
with t as (
           select  xmlparse(content '<Data>
  <EMPLOYER>
    <SUMMARY>
      <WORKER>
        <RESULT_DETAIL>
          <CLASS>z</CLASS>
        </RESULT_DETAIL>
      </WORKER>
    </SUMMARY>
  </EMPLOYER>
</Data>
<Bug>
  <ID>12345</ID>
</Bug>') x from dual
          )
select  xmlcast(xmlquery('/Data/EMPLOYER/SUMMARY/WORKER/RESULT_DETAIL/CLASS' passing x returning content) as varchar2(10)) class,
        xmlcast(xmlquery('/Bug/ID' passing x returning content) as number) bug_id
  from  t
/

CLASS          BUG_ID
---------- ----------
z               12345

SQL>



SY.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как проверить, что в поле - XML? / 22 сообщений из 22, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]