Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вставка в XML недостающего тега / 14 сообщений из 14, страница 1 из 1
13.12.2018, 17:09
    #39747530
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Добрый день всем! Копаюсь в просторах интернета и никак не могу найти нужный мне вариант обработки xml.
Суть такая - есть xml файл, в нем приблизительно такая структура:
Код: xml
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.
<root> 
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>

  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
     </Item>
  </Card>

  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>

</root>



В одном из <Item> нет тега <Par3>. Как можно обнаружить такое место и добавить этот тэг?
...
Рейтинг: 0 / 0
13.12.2018, 17:28
    #39747551
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Dr_Grizzlyдобавить этот тэгвсе равно, какое значение?
...
Рейтинг: 0 / 0
13.12.2018, 17:45
    #39747555
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Да, все равно
...
Рейтинг: 0 / 0
13.12.2018, 17:57
    #39747564
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Dr_GrizzlyДа, все равно

Код: 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.
with t as (
   select xmltype('
<root> 
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>

  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
     </Item>
  </Card>

  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>

</root>
'
) x
   from dual
)
select *
  from t
      ,xmltable('/root/*' passing t.x columns
                    a0 for ordinality
                   ,a1 varchar2(100) path '/Card/Item/Par1'
                   ,a2 varchar2(100) path '/Card/Item/Par2'
                   ,a3 varchar2(100) path '/Card/Item/Par3'
                );

...
Рейтинг: 0 / 0
13.12.2018, 18:24
    #39747582
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Спасибо, только не пойму что получается - матрица с тремя строками, в первой колонке содержание xml, во второй колонке последовательность 1-2-3 по строкам. а остальные две пустые...
...
Рейтинг: 0 / 0
13.12.2018, 18:31
    #39747587
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
<XMLTYPE> 1 100355159 -1 2014-07-22T00:00:00 2014-07-24T00:00:00 11
<XMLTYPE> 2 100355159 -1 2014-07-25T00:00:00 2018-12-03T00:00:00 10
<XMLTYPE> 3 100355159 -1 2014-07-16T00:00:00 2014-07-21T00:00:00 10
<XMLTYPE> 4 100355159 -1 1970-01-01T00:00:00 2013-02-21T00:00:00 11
<XMLTYPE> 5 100355159 -1 2013-02-22T00:00:00 2014-07-15T00:00:00 10
<XMLTYPE> 6 100355159 -1 2018-12-04T00:00:00 9999-01-01T00:00:00


Немного ошибся я в коде когда преобразовывал. вообще вот что выдал запрос - в последней колонке в последней строке нет значения - как раз то место, где нет нужного тега. А теперь как его туда воткнуть можно? )
...
Рейтинг: 0 / 0
13.12.2018, 19:02
    #39747607
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Dr_GrizzlyСпасибо, только не пойму что получается - матрица с тремя строками, в первой колонке содержание xml, во второй колонке последовательность 1-2-3 по строкам. а остальные две пустые...
:)

Код: 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.
with t as (select xmltype('<root> 
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
     </Item>
  </Card>
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>
</root>') f from dual
)-----------------------------
select XMLSerialize( document
                     xmlelement( "root"
                               , xmlagg(xmlelement( "Card"
                                                  , xmlelement( "Item"
                                                               , xmlelement("Par1", "Par1"), xmlelement("Par2", "Par2"), xmlelement("Par3", "Par3")
                                                               )
                               )))
                 --as varchar2(2000)
                 --as blob encoding 'utf-8'
                 indent size = 1
                 )
  from (
        select x.* 
          from t, xmltable('/root/Card/Item'
          passing f
          columns "Par1", "Par2", "Par3"
          ) x
       )  



Только не делайте так.
Если принципиально внутри oracle - то зарегистрируйте схему и воспользуйтесь XMLSerialize SHOW DEFAULTS, оно умеет.
...
Рейтинг: 0 / 0
13.12.2018, 19:07
    #39747610
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Dr_GrizzlyВ одном из <Item> нет тега <Par3>. Как можно обнаружить такое место и добавить этот тэг?

Ну если знаем имена всех тегов под Item:

Код: 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.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
drop table tbl purge
/
create table tbl
as select xmltype('<root> 
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
     </Item>
  </Card>
  <Card>
     <Item>
       <Par1>123</Par1>
       <Par2>AAADDDD</Par2>
       <Par3>9999</Par3>
     </Item>
  </Card>
</root>') x from dual
/
with t as (
           select card_no,
                  xmlagg(
                         xmlelement(
                                    "Item",
                                    xmlelement("Par1",par1),
                                    xmlelement("Par2",par2),
                                    xmlelement("Par3",nvl(par3,'some value'))
                                   )
                        ) item
             from tbl,
                  xmltable(
                           '/root/Card'
                           passing x
                           columns
                             card_no for ordinality,
                             card xmltype path '/Card/Item'
                           ) x,
                  xmltable(
                           '/Item'
                           passing card
                           columns
                             item_no for ordinality,
                             par1 varchar2(10) path '/Item/Par1',
                             par2 varchar2(10) path '/Item/Par2',
                             par3 varchar2(10) path '/Item/Par3'
                           ) y
             group by card_no,
                      item_no
           )
select xmlserialize(
                    document
                    xmlelement(
                               "root",
                               xmlagg(
                                      xmlelement(
                                                 "Card",
                                                 xmlagg(
                                                        item
                                                       )
                                                )
                                     )
                              )
                    indent
                      size = 2
                   )
  from t
  group by card_no
/

XMLSERIALIZE(DOCUMENTXMLELEMENT("ROOT",XMLAGG(XMLELEMENT("CARD",XMLAGG(ITEM))))I
--------------------------------------------------------------------------------
<root>
  <Card>
    <Item>
      <Par1>123</Par1>
      <Par2>AAADDDD</Par2>
      <Par3>9999</Par3>
    </Item>
  </Card>
  <Card>
    <Item>
      <Par1>123</Par1>
      <Par2>AAADDDD</Par2>
      <Par3>some value</Par3>
    </Item>
  </Card>
  <Card>
    <Item>
      <Par1>123</Par1>
      <Par2>AAADDDD</Par2>
      <Par3>9999</Par3>
    </Item>
  </Card>
</root>


SQL> 



Но основой вопрос может ли Par3 быть NULL? Если да, то использование xmlelement("Par3",par3) в COLUMNS не отделаешься и придется проверять само наличие тега Par3.

SY.
...
Рейтинг: 0 / 0
13.12.2018, 20:21
    #39747631
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
andrey_anonymousзарегистрируйте схему и воспользуйтесь XMLSerialize SHOW DEFAULTS, оно умеет.
Код: 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.
75.
76.
begin
  dbms_xmlschema.registerSchema(schemaURL => 'http://myschema'
  , schemaDoc => '<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="root">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="Card" maxOccurs="unbounded">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Item" maxOccurs="unbounded">
                  <xs:complexType>
                    <xs:sequence>
                      <xs:element name="Par1" type="xs:string"/>
                      <xs:element name="Par2" type="xs:string"/>
                      <xs:element name="Par3" type="xs:string" default="DefaultValue"/>
                    </xs:sequence>
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
</xs:schema>'
  , local => true);
end;
/
PL/SQL procedure successfully completed


with t as (select xmltype('<root>
     <Card><Item><Par1>123</Par1><Par2>AAADDDD</Par2><Par3>9999</Par3></Item></Card>
     <Card><Item><Par1>123</Par1><Par2>AAADDDD</Par2>                 </Item></Card>
     <Card><Item><Par1>123</Par1><Par2>AAADDDD</Par2><Par3>9999</Par3></Item></Card>
     </root>'
,'http://myschema'
) f
from dual
)-----------------------------
select XMLSerialize( document f
                 as varchar2(2000)
                 --as blob encoding 'utf-8'
                 indent size = 1
                 show defaults
                 )
  from t
;
XMLSERIALIZE(DOCUMENTFASVARCHA
--------------------------------------------------------------------------------
<root>
 <Card>
  <Item>
   <Par1>123</Par1>
   <Par2>AAADDDD</Par2>
   <Par3>9999</Par3>
  </Item>
 </Card>
 <Card>
  <Item>
   <Par1>123</Par1>
   <Par2>AAADDDD</Par2>
   <Par3>DefaultValue</Par3>
  </Item>
 </Card>
 <Card>
  <Item>
   <Par1>123</Par1>
   <Par2>AAADDDD</Par2>
   <Par3>9999</Par3>
  </Item>
 </Card>
</root>

SQL> 

...
Рейтинг: 0 / 0
14.12.2018, 08:05
    #39747708
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Истина где-то рядом ))
Нашел еще одну штуку, но чуток не дотягиваю как поставить условие НЕ

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with xmltab as
( select sys_nc_rowinfo$ as FXML from myxml t)

SELECT XMLQuery(
'copy $NEWXML := $XML modify (
  for $i in $NEWXML/root/card/item
    where exists($i/Par3)  ---как сказать Не существует??? в таком виде работает для всех где есть ))
     return insert node <Pa3>AASS</Par3> into $i
 )
 return $NEWXML'
 passing FXML as "XML",
         'TEST' as "NAME"
 returning CONTENT
)
from xmltab
;
...
Рейтинг: 0 / 0
14.12.2018, 09:01
    #39747727
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Ура товарищи! Получилось! Спасибо вам за помощь!

Вот последний вариант
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with xmltab as
( select sys_nc_rowinfo$ as FXML from myxml t)

SELECT XMLQuery(
'copy $NEWXML := $XML modify (
  for $i in $NEWXML/PACKAGE/POSTOBJECT/CD/SMCARDTAX
    where not(exists($i/TAXGROUPID))
     return insert node <name>thenname</name> into $i
 )
 return $NEWXML'
 passing FXML as "XML",
         'TEST' as "NAME"
 returning CONTENT
)
from xmltab
;
...
Рейтинг: 0 / 0
14.12.2018, 09:02
    #39747729
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Dr_Grizzlyкак поставить условие НЕВеликая тайна, посмотреть в спецификации xquery функцию not, доступна не всем. Кстати, наличие значения само по себе логическое выражение, поэтому exists излишен. Ну и еще вариант - вообще не проверять существование, а брать "nvl".
Если структура xml известна целиком, то можно обойтись и без modify, обеспечив совместимость со старыми версиями БД:
Код: sql
1.
2.
3.
4.
<root><Card>{
for $x in /root/Card/Item
return <Item>{$x/Par1,$x/Par2,($x/Par3,element Par3{})[1]}</Item>
}</Card></root>


Закладываться на обязательное наличие пустого элемента плохой тон. Задавать в схеме nillable и потом в xml писать атрибут nil=true излишне громоздко. Переопределять всякие int как строку, чтобы вместить пустое значение тоже не самое удачное решение.
...
Рейтинг: 0 / 0
19.12.2018, 14:27
    #39750209
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
-2-,

Хорошая мысль! Я ее покурю в перерыве. Спасибо!


Есть еще момент интересный ))
Сначала я хотел вставлять в недостающий тэг константное значение, но задачка немного усложнилась и теперь хочу туда втыкать параметр. Кручу xmlQuery по всякому, и прийти к результату не получается...
Возьмем уже работающий код и попробуем немного его подпилить
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
declare
v_taxgroup_val varchar2(10);
...
with xmltab as
            (select xmltype(v_clob) as FXML, v_taxgroup_val from dual)
          select XMLQuery('copy $NEWXML := $XML modify (
                            for $i in $NEWXML/PACKAGE/POSTOBJECT/CD/SMCARDTAX
                              where not(exists($i/TAXGROUPID))
                               return insert node <TAXGROUPID> $TAXGP </TAXGROUPID> into $i
                           )
                           return $NEWXML'
                           passing FXML as "XML",
                           v_taxgroup_val as "TAXGP",
                           'TEST' as "NAME"
                           returning CONTENT
                          )
            into v_xmltype
            from xmltab


такой вариант не прокатывает. Вставляет прям текстом "$TAXGP"...
Пробовал исключить из select и просто конкатенацию строк делать. не помогло

Явно где-то маленькая палочка в колесе застряла... Есть предложения как это можно победить?
...
Рейтинг: 0 / 0
19.12.2018, 15:03
    #39750229
Dr_Grizzly
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка в XML недостающего тега
Победил задачку!

Вот результат:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
with xmltab as
            (select xmltype(v_clob) as FXML from dual)
          select XMLQuery('copy $NEWXML := $XML modify (
                            for $i in $NEWXML/PACKAGE/POSTOBJECT/CD/SMCARDTAX
                              where not(exists($i/TAXGROUPID))
                               return insert node $TAG_TAX into $i
                           )
                           return $NEWXML'
                           passing FXML as "XML",                          
                           xmltype('<TAXGROUPID>'||v_taxgroup_val||'</TAXGROUPID>') as "TAG_TAX"
                           returning CONTENT
                          )
            into v_xmltype
            from xmltab;
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вставка в XML недостающего тега / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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