powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как проверить, что в поле - XML?
22 сообщений из 22, страница 1 из 1
Как проверить, что в поле - XML?
    #40087212
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ, всем привет!
И вроде простой вопрос, но найти ответ пока не смог. Может и плохо искал, конечно...
Но всё же, как сделать так, чтобы данный запрос выполнился, вернув одну строку, с корректным 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
Как проверить, что в поле - XML?
    #40087217
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087239
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник

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

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

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

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

Ну вот да. Была ещё мыль про VALIDATE_CONVERSION, но она не понимает xmltype
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087327
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как проверить, что в поле - XML?
    #40087334
qlost
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если xml-ка большая, можно заюзать SAX
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087335
Bsplesk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
del
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087428
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY

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

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

Synoptic

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

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


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

SY.
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087463
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как проверить, что в поле - XML?
    #40087465
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Synoptic,
Я бы из функции возвращал сам xmltype, чтобы дважды не конвертить.
И null в случае exception.
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087477
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разумно!
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087534
qlost
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087536
Фотография 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.
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40087568
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как проверить, что в поле - XML?
    #40087582
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И никто так и не скажет, что у аффтара оба XML одинаково валидные/инвалидные с точки
зрения спецификации?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40088181
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
И никто так и не скажет, что у аффтара оба XML одинаково валидные/инвалидные с точки
зрения спецификации?..

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

Корень XML это тэг <xml>. Он отсутствует в обоих вариантах. Да, в этом случае там могут
быть сколько угодно разных "корней".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40088340
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov, хочешь сказать, что оракловый xmltype() работает некорректно?
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40088350
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как проверить, что в поле - XML?
    #40088456
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
22 сообщений из 22, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как проверить, что в поле - XML?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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