Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 xml конвертация  [new]
ээээээээ
Guest
Народ, подскажите советом

Есть XML

<documents>
<document>
<number>1</number>
<persons>
<person>
<name>Вася</name>
<family>Васечкин</family>
</person>
<person>
<name>Петя</name>
<family>Петров</family>
</person>
</persons>
</document>
<document>
<number>2</number>
<persons>
<person>
<name>Василий</name>
<family>Пупкин</family>
</person>
</persons>
</document>
</documents>

задача получить XML в такой структуре (похожа, но теги по другому называются и кое что еще добавляется)

<projects>
<project>
<num>1</num>
<subjects>
<subject num=1>
<name>Вася</name>
<family>Васечкин</family>
</subject>
<subject num=2>
<name>Петя</name>
<family>Петров</family>
</subject>
</subjects>
</project>
<project>
<num>2</num>
<subjects>
<subject num=1>
<name>Василий</name>
<family>Пупкин</family>
</subject>
</subjects>
</project>
</projects>


как это сделать, используя XMLElement, XMLAttributes (без XSL) ???
у меня проблема с Subjects, пишет "подзопрос одиночной строки..."
2 июл 09, 15:42    [7369235]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
ээээээээ
у меня проблема с Subjects, пишет "подзопрос одиночной строки..."

Прям вот сам XML и пишет? Вы его не трогаете, а он все пишет и пишет?
ээээээээ
как это сделать, используя XMLElement, XMLAttributes (без XSL) ???

with t as(
select XMLType('<documents>
  <document>
  <number>1</number>
  <persons>
    <person>
      <name>Вася</name>
      <family>Васечкин</family>
    </person>
    <person>
      <name>Петя</name>
      <family>Петров</family>
    </person>
  </persons>
  </document>
  <document>
    <number>2</number>
    <persons>
      <person>
      <name>Василий</name>
      <family>Пупкин</family>
    </person>
  </persons>
  </document>
  </documents>') XML
  from dual
)
select
  xmlElement("projects",
              xmlagg(XmlElement("project"
                        ,XMLForest("num"
                                   ,xmlagg(
                                       XMlElement("subject"
                                                  ,XMLAttributes(RN as "num"
                                                   )
                                                  ,XMLForest(
                                                    "name"
                                                    ,"family"
                                                  )
                                       )
                                   ) "subjects"
                         )
                     )
              )
   )
   /*--*/.extract('*').getStringVal() -- эту строку закоментировать
   XML
from
(
 select
   extractValue(value(document),'document/number') "num"
  ,extractValue(value(person),'person/name') "name"
  ,extractValue(value(person),'person/family') "family"
  ,row_number() over (partition by (extractValue(value(document),'document/number')) order by null) RN
  from t
       ,table(XMLSequence(extract(t.XML,'documents/document'))) document
       ,table(XMLSequence(extract(value(document),'document/persons/person'))) person
)
group by "num";
 
XML
--------------------------------------------------------------------------------
<projects>
  <project>
    <num>1</num>
    <subjects>
      <subject num="1">
        <name>Вася</name>
        <family>Васечкин</family>
      </subject>
      <subject num="2">
        <name>Петя</name>
        <family>Петров</family>
      </subject>
    </subjects>
  </project>
  <project>
    <num>2</num>
    <subjects>
      <subject num="1">
        <name>Василий</name>
        <family>Пупкин</family>
      </subject>
    </subjects>
  </project>
</projects>
 
SQL>  
2 июл 09, 16:25    [7369580]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
ээээээээ
Guest
чтото у меня не отрабатывает ваш примерчик,но идея ясна..спасибо
2 июл 09, 16:52    [7369750]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
ээээээ
Guest
а ларчик просто открывался))... спасибо еще раз
2 июл 09, 16:59    [7369791]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
Zloxa,

а если в этот пример добавить еще одну вложенность, например так :

<projects>
<project>
<num>1</num>
<subjects>
<subject num="1">
<name>Вася</name>
<family>Васечкин</family>
</subject>
<subject num="2">
<name>Петя</name>
<family>Петров</family>
</subject>
</subjects>
<adresess>
<adreses subject_num =1>
<addr_string></addr_string>
</adreses>
<adreses subject_num =2>
<addr_string></addr_string>
</adreses>
</adresess>

</project>
<project>
<num>2</num>
<subjects>
<subject num="1">
<name>Василий</name>
<family>Пупкин</family>
</subject>
</subjects>
</project>
</projects>
получим ошибку ORA-00935: group function is nested too deeply

судя по предложенному здесь тынц решению, выход есть. Но если таких группировок много (штук 10) не фишимебельно же для каждого накручивать сверху "select from select".

Может кто то имел дело стакими ситуациями, есть еще какие нибудь варианты решения?
3 июл 09, 13:00    [7373051]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
marky4
Но если таких группировок много (штук 10) не фишимебельно же для каждого накручивать сверху "select from select".

Почему?
Можно еще скалярами выбираться, но select from select, мне кажется правильнее.
Чтоб не потерять в читабельности - with.
3 июл 09, 16:08    [7374533]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
а можно блок
 <adresess>
<adreses subject_num =1>
<addr_string></addr_string>
</adreses>
<adreses subject_num =2>
<addr_string></addr_string>
</adreses>
</adresess>
как то формировать отдельно и потом соединять как то с остальными данными? :)
3 июл 09, 16:10    [7374546]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
Zloxa,

ну что ж , щас попробую..но такое трехэтажное получится.....
3 июл 09, 16:12    [7374566]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
marky4,

вы бы не только в результат корректировки вносили, но и в исходные данные...
3 июл 09, 16:16    [7374592]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
Zloxa
marky4,

вы бы не только в результат корректировки вносили, но и в исходные данные...

эт как?
3 июл 09, 16:29    [7374696]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
имею в исходных данных следующее количество :
policy=1 запись
person =7 записей
autovehicle =1 запись

пишу :
from table(XMLSequence(extract(xmlType(src),'export/policys/policy')))             policy
,table(XMLSequence(extract(value(policy),'policy/persons/person'))) person
,table(XMLSequence(extract(value(policy),'policy/autovehicles/autovehicle'))) ts
ровно так и получаю.

добавляю еще одну структуру (riskobject =2 записи)

from table(XMLSequence(extract(xmlType(src),'export/policys/policy')))             policy
,table(XMLSequence(extract(value(policy),'policy/persons/person'))) person
,table(XMLSequence(extract(value(policy),'policy/autovehicles/autovehicle'))) ts
,table(XMLSequence(extract(value(ts),'autovehicle/riskobjects/riskobject'))) risks

и у меня все двоится. почему получается декартово произведение? как от него избавится?
5 июл 09, 19:02    [7378149]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
marky4,
Это очень хорошо что Вы показали как Вы делаете и что вас не устраивает в результате.
Этой информации вполне достаточно чтбы проявить к Вам сочувствие, которое я искренне спешу Вам выразить. Но если Вы все же ожидаете еще какой либо помощи, то приведите ко всему еще и пример исходных данных, и пример результата, который Вас смог бы удовлетворить.
Желательно при этом создать новый топик, потому что ваш вопрос, по всей видимости, никоим образом не связан с вопросом ээээээээ
6 июл 09, 00:14    [7378597]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116283
Zloxa
marky4,
Это очень хорошо что Вы показали как Вы делаете и что вас не устраивает в результате.
Этой информации вполне достаточно чтбы проявить к Вам сочувствие, которое я искренне спешу Вам выразить. Но если Вы все же ожидаете еще какой либо помощи, то приведите ко всему еще и пример исходных данных, и пример результата, который Вас смог бы удовлетворить.
Желательно при этом создать новый топик, потому что ваш вопрос, по всей видимости, никоим образом не связан с вопросом ээээээээ


Тем не менее ответить на вопрос о декартовом произведении можно

7*1*1 = 7
7*1*1*2 = 14

6 июл 09, 00:17    [7378604]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
dmidek, Тут чуть другая математика, здесь есть левая корреляция, но и декартово произведение тоже присутствует ;)
6 июл 09, 01:07    [7378716]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116

<policys>
<policy>
<num>1</num>
<subjects>
<subject num="1">
<name>Вася</name>
<family>Васечкин</family>
</subject>
<subject num="2">
<name>Петя</name>
<family>Петров</family>
</subject>
</subjects>
<transport>
<mark>toyota</mark>
<usages>
<users subj_num =2>
</users>
</usages>
</transport>
<risks>
<risk>
<risk_no>1<risk_no>
</risk>
<risk>
<risk_no>2<risk_no>
</risk>
</risks>
</project>
<project>
<num>2</num>
<subjects>
<subject num="1">
<name>Василий</name>
<family>Пупкин</family>
</subject>
</subjects>
...
</policy>
</policys>




declare
xmlsrc xmlType;
res clob;
begin
select XMLType('<documents>
<document>
<number>1</number>
<persons>
<person>
<name>Вася</name>
<family>Васечкин</family>
</person>
<person>
<name>Петя</name>
<family>Петров</family>
</person>
</persons>
<cars>
<car>
<mark>toyota</mark>
<risks>
<risk>
<risk_no>1</risk_no>
</risk>
<risk>
<risk_no>2</risk_no>
</risk>
</risks>
</car>
</cars>
</document>
<document>
<number>2</number>
<persons>
<person>
<name>Василий</name>
<family>Пупкин</family>
</person>
</persons>
</document>
</documents>') XML
into xmlsrc
from dual;


select
xmlElement("projects",
xmlagg(XmlElement("project"
,XMLForest("num"
,xmlagg(
XMlElement("subject"
,XMLAttributes(RN as "num"
)
,XMLForest(
"name"
,"family"
)
)
) "subjects"
),
XMLForest("num",XMLelement("mark", "mark") "transport")
)
)
)
/*--*/.extract('*').getStringVal() -- эту строку закоментировать
XML
into res
from
(
select
extractValue(value(document),'document/number') "num"
,extractValue(value(person),'person/name') "name"
,extractValue(value(person),'person/family') "family"
,extractValue(value(car),'car/mark') "mark"
,extractValue(value(risk),'risk/risk_no') "risk"
,row_number() over (partition by (extractValue(value(document),'document/number')) order by null) RN
from
table(XMLSequence(extract(xmlsrc,'documents/document'))) document
,table(XMLSequence(extract(value(document),'document/persons/person'))) person
,table(XMLSequence(extract(value(document),'document/cars/car'))) car
,table(XMLSequence(extract(value(car),'car/risks/risk'))) risk
)
group by "num","mark";

dbms_output.put_line(res);

end;
6 июл 09, 11:26    [7379574]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
извиняюсь ,не туда нажал...
собственно, первый xml это то,что надо получить. Дальше приводится исходные данные и то как я получаю результат.
Откуда берется декартово произведение я понимаю, но тока как от него избавится -не пойму
6 июл 09, 11:29    [7379594]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
marky4,

<users subj_num =2>
Почему 2 а не 1? В смысле как правильный subj_num определить по исходному XML?
6 июл 09, 11:49    [7379761]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
Zloxa,

а да извиняюсь... в исходном xml есть признак is_user = 1


<policys>
<policy>
<num>1</num>
<subjects>
<subject num="1">
<is_user>0</is_user>
<name>Вася</name>
<family>Васечкин</family>
</subject>
<subject num="2">
<is_user>1</is_user>
<name>Петя</name>
<family>Петров</family>
</subject>
</subjects>
<transport>
<mark>toyota</mark>
<usages>
<users subj_num =2>
</users>
</usages>
</transport>
<risks>
<risk>
<risk_no>1<risk_no>
</risk>
<risk>
<risk_no>2<risk_no>
</risk>
</risks>
</project>
<project>
<num>2</num>
<subjects>
<subject num="1">
<name>Василий</name>
<family>Пупкин</family>
</subject>
</subjects>
...
</policy>
</policys>
6 июл 09, 12:08    [7379918]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
marky4
в исходном xml есть признак is_user = 1

Это просто замечательно!!!!
Только почему вы этот признак показали в результирующем XML, а исходный держите в рукаве?

Как бы там ни было, думаю с меня хватит, Ваша неспособность изложить Ваши потребности начинает изрядно раздражать, боюсь я не настроен более на конструктив.
6 июл 09, 12:25    [7380038]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
Zloxa,
я дико извиняюсь, накосячил.... во-первых спасибо большое что уделяете (уделяли) свое внимание, Вы мне очень сильно помогли своим ответом для эээээээ.
собственно, сейчас есть два вопроса
Есть исходные данные


<documents>
<document>
<number>1</number>
<persons>
<person>
<is_user>0</is_user>
<is_owner>1</is_owner>
<name>Вася</name>
<family>Васечкин</family>
</person>
<person>
<is_user>1</is_user>
<is_owner>0</is_owner>
<name>Петя</name>
<family>Петров</family>
</person>
</persons>
<cars>
<car>
<mark>toyota</mark>
<risks>
<risk>
<risk_no>1</risk_no>
</risk>
<risk>
<risk_no>2</risk_no>
</risk>
</risks>
</car>
</cars>
</document>
</documents>

требуется получить :

<policys>
<policy>
<num>1</num>
<subjects>
<subject num="1">
<name>Вася</name>
<family>Васечкин</family>
</subject>
<subject num="2">
<name>Петя</name>
<family>Петров</family>
</subject>
</subjects>
<transport>
<mark>toyota</mark>
<usages>
<users subj_num =2>
</users>
</usages>
</transport>
<risks>
<risk>
<risk_no>1<risk_no>
</risk>
<risk>
<risk_no>2<risk_no>
</risk>
</risks>
</project>
</policy>
</policys>

делаю следующим образом :

declare 
xmlsrc xmlType;
res clob;
begin
select XMLType('<documents>
<document>
<number>1</number>
<persons>
<person>
<is_user>0</is_user>
<is_owner>1</is_owner>
<name>Вася</name>
<family>Васечкин</family>
</person>
<person>
<is_user>1</is_user>
<is_owner>0</is_owner>
<name>Петя</name>
<family>Петров</family>
</person>
</persons>
<cars>
<car>
<mark>toyota</mark>
<risks>
<risk>
<risk_no>1</risk_no>
</risk>
<risk>
<risk_no>2</risk_no>
</risk>
</risks>
</car>
</cars>
</document>
</documents>') XML
into xmlsrc
from dual;


select
xmlElement("projects",
xmlagg(XmlElement("project"
,XMLForest("num"
,subjects "subjects"
),transport

)
)
)
/*--*/.extract('*').getStringVal() -- эту строку закоментировать
XML
into res
from
(
select
xmlagg(
XMlElement("subject"
,XMLAttributes(RN as "num"
)
,XMLForest(
"name"
,"family"
)
)
) subjects
,XMLAgg( case when "is_owner" = '1' then
XMLelement("transport",
XMLAttributes(RN as "subj_num"),
XMLelement("mark","mark")
)
else null end) transport
,XMLAgg( case when "is_user" = '1' then
XMLelement("usages",
XMLAttributes(RN as "subj_num")
)
else null end) users
,"mark"
,"num"

from
(
select
extractValue(value(document),'document/number') "num"
,extractValue(value(person),'person/name') "name"
,extractValue(value(person),'person/family') "family"
,extractValue(value(car),'car/mark') "mark"
,extractValue(value(person),'person/is_owner') "is_owner"
,extractValue(value(person),'person/is_user') "is_user"
-- ,extractValue(value(risk),'risk/risk_no') "risk"
,row_number() over (partition by (extractValue(value(document),'document/number')) order by null) RN
from
table(XMLSequence(extract(xmlsrc,'documents/document'))) document
,table(XMLSequence(extract(value(document),'document/persons/person'))) person
,table(XMLSequence(extract(value(document),'document/cars/car'))) car
-- ,table(XMLSequence(extract(value(car),'car/risks/risk'))) risk
)
group by "num","mark");

dbms_output.put_line(res);

end;


вопрос №1 - при раскоментировании "risk" получаю декартово произведение и левую корелляцию как заметил Zloxa - как от не избавится
а вопрос №2 - вложить тег users в тег transport

заранее спасибо за советы
6 июл 09, 13:03    [7380319]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
вот реализация вопроса №1 :

declare 
xmlsrc xmlType;
res clob;
begin
select XMLType('<documents>
<document>
<number>1</number>
<persons>
<person>
<is_user>0</is_user>
<is_owner>1</is_owner>
<name>Вася</name>
<family>Васечкин</family>
</person>
<person>
<is_user>1</is_user>
<is_owner>0</is_owner>
<name>Петя</name>
<family>Петров</family>
</person>
</persons>
<cars>
<car>
<mark>toyota</mark>
<risks>
<risk>
<risk_no>1</risk_no>
</risk>
<risk>
<risk_no>2</risk_no>
</risk>
</risks>
</car>
</cars>
</document>
</documents>') XML
into xmlsrc
from dual;


select
xmlElement("projects",
xmlagg(XmlElement("project"
,XMLForest("num"
,subjects "subjects"
),transport,
XMLElement("RISKS"),risk

)
)
)
/*--*/.extract('*').getStringVal() -- эту строку закоментировать
XML
into res
from
(
select
xmlagg(
XMlElement("subject"
,XMLAttributes(RN as "num"
)
,XMLForest(
"name"
,"family"
)
)
) subjects
,XMLAgg( case when "is_owner" = '1' then
XMLelement("transport",
XMLAttributes(RN as "subj_num"),
XMLelement("mark","mark")
)


else null end) transport
,XMLAgg( case when "is_user" = '1' then
XMLelement("usages",
XMLAttributes(RN as "subj_num")
)

else null end) users
,XMLAgg(
XMLelement("risk",
XMLAttributes("risk" as "risk_no")
) )risk
,"mark"
,"num"

from
(
select
extractValue(value(document),'document/number') "num"
,extractValue(value(person),'person/name') "name"
,extractValue(value(person),'person/family') "family"
,extractValue(value(car),'car/mark') "mark"
,extractValue(value(person),'person/is_owner') "is_owner"
,extractValue(value(person),'person/is_user') "is_user"
,extractValue(value(risk),'risk/risk_no') "risk"
,row_number() over (partition by (extractValue(value(document),'document/number')) order by null) RN
from
table(XMLSequence(extract(xmlsrc,'documents/document'))) document
,table(XMLSequence(extract(value(document),'document/persons/person'))) person
,table(XMLSequence(extract(value(document),'document/cars/car'))) car
,table(XMLSequence(extract(value(car),'car/risks/risk'))) risk
)
group by "num","mark");

dbms_output.put_line(res);

end;
6 июл 09, 13:19    [7380441]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
народ, вопрос очень актуальный... плиз нид хелп
7 июл 09, 09:20    [7384145]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
VBR
Member

Откуда:
Сообщений: 79
Может легче через XSL преобразование в частном случае решить
Пример, дальше по аналогии.

select XMLType.transform( xmltype(
'<documents>  
   <document>  
      <number>1</number>  
       <persons>  
        <person>   
           <is_user>0</is_user>   
           <is_owner>1</is_owner>   
           <name>Вася</name>   
          <family>Васечкин</family>  
       </person>  
       <person>  
           <is_user>1</is_user> 
           <is_owner>0</is_owner> 
           <name>Петя</name>  
           <family>Петров</family>  
       </person> 
      </persons>
      <cars>
          <car>  
             <mark>toyota</mark>  
             <risks>
               <risk> 
                <risk_no>1</risk_no> 
              </risk> 
              <risk> 
                 <risk_no>2</risk_no>  
             </risk> 
           </risks>
         </car> 
      </cars> 
   </document>  
 </documents>'
),  
xmltype(
'<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">
  <xsl:template match="/">
    <policys>
    <xsl:for-each select="documents/document">
      <policy>
        <num><xsl:value-of select="number"/></num>
         <subjects>
            <xsl:for-each select="persons/person">
              <subject><xsl:attribute name="num"> <xsl:number value="position()" format="1"/></xsl:attribute>
                <name><xsl:value-of select="name"/></name>
                <family><xsl:value-of select="family"/></family>
              </subject>
           </xsl:for-each>   
        </subjects>
     </policy>
     </xsl:for-each>
    </policys>
  </xsl:template>
</xsl:stylesheet>'                                 
)).getClobVal() from dual
7 июл 09, 10:18    [7384422]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
VBR
Member

Откуда:
Сообщений: 79
http://www.citforum.ru/internet/xslt/xslt.shtml
7 июл 09, 10:19    [7384430]     Ответить | Цитировать Сообщить модератору
 Re: xml конвертация  [new]
marky4
Member

Откуда: москва
Сообщений: 116
нет, XSL в этой задаче я к сожалению не могу использовать..хотя изначально он рассматривался.
7 июл 09, 11:37    [7385030]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить