powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вставка в XML недостающего тега
14 сообщений из 14, страница 1 из 1
Вставка в XML недостающего тега
    #39747530
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день всем! Копаюсь в просторах интернета и никак не могу найти нужный мне вариант обработки 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
Вставка в XML недостающего тега
    #39747551
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dr_Grizzlyдобавить этот тэгвсе равно, какое значение?
...
Рейтинг: 0 / 0
Вставка в XML недостающего тега
    #39747555
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, все равно
...
Рейтинг: 0 / 0
Вставка в XML недостающего тега
    #39747564
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Вставка в XML недостающего тега
    #39747582
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, только не пойму что получается - матрица с тремя строками, в первой колонке содержание xml, во второй колонке последовательность 1-2-3 по строкам. а остальные две пустые...
...
Рейтинг: 0 / 0
Вставка в XML недостающего тега
    #39747587
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
<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
Вставка в XML недостающего тега
    #39747607
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Вставка в XML недостающего тега
    #39747610
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Вставка в XML недостающего тега
    #39747631
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Вставка в XML недостающего тега
    #39747708
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Истина где-то рядом ))
Нашел еще одну штуку, но чуток не дотягиваю как поставить условие НЕ

Код: 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
Вставка в XML недостающего тега
    #39747727
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ура товарищи! Получилось! Спасибо вам за помощь!

Вот последний вариант
Код: 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
Вставка в XML недостающего тега
    #39747729
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Вставка в XML недостающего тега
    #39750209
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-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
Вставка в XML недостающего тега
    #39750229
Dr_Grizzly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Победил задачку!

Вот результат:
Код: 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
14 сообщений из 14, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вставка в XML недостающего тега
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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