Помогите разобрать xml в таблицу

Vitaly86
Дата: 18.01.2009 17:33:05
Только начал разбираться с возможностями работы с xml из MsSQL 2005.
Какие то простые примеры уже получаются, но мне нужно распарсить xml содержаший элементы с ":"
Подозреваю что нужно как то определять, работать со схемами,
но что с ним делать совершенно не понятно.

в примере нужно разобрать закомментированный @xml2

declare @xml1 xml, @xml2 xml

set @xml2 = '<root> <t> ' +
            ' <n>1</n> ' +
            ' <vdate dt="2009-01-18">' +
            '   <vtime>18:05</vtime> '+
            '   <vtime>18:35</vtime> '+
            ' </vdate>'+
            ' </t> '+
            ' <t> ' +
            ' <n>2</n> ' +
            ' <vdate dt="2009-01-20">' +
            '   <vtime>20:05</vtime> '+
            '   <vtime>20:35</vtime> '+
            ' </vdate>'+
            ' </t> </root>'

  create table #t ( XmlDescription xml )
     
/*
set @xml2 = '<root> <t> ' +
            ' <n>1</n> ' +
            ' <v:date dt="2009-01-18">' +
            '   <v:time>18:05</v:time> '+
            '   <v:time>18:35</v:time> '+
            ' </v:date>'+
            ' </t> '+
            ' <t> ' +
            ' <n>2</n> ' +
            ' <v:date dt="2009-01-20">' +
            '   <v:time>20:05</v:time> '+
            '   <v:time>20:35</v:time> '+
            ' </v:date>'+
            ' </t> </root>'
*/

  insert into #t 
  select  @xml2

select n
     , vdate
     , T2.Loc.value('text()[1]', 'varchar(50)') vtime
from (
select n
     , T2.Loc.value('@dt', 'varchar(50)') vdate
     , T2.Loc.query('vtime') x
from ( select T2.Loc.value('n[1]', 'varchar(50)') n
            , T2.Loc.query('vdate') x
         from #t T 
         CROSS APPLY XmlDescription.nodes('/root/t') as T2(Loc)       
      ) t
         CROSS APPLY x.nodes('/vdate' ) as T2(Loc)
   ) t
         CROSS APPLY x.nodes('vtime' ) as T2(Loc)

drop table #t

после того как данные попадут в таблицу, мне нужно собрать их в xml другой структуры
сейчас собираю запросом
select .....  for xml auto, type, elements 

но может быть можно тоже самое сделать через ssis объектом "XML Task"?
Кто нибудь пробовал? поделитесь пожалуйста примером.
Mnior
Дата: 18.01.2009 19:39:50
Vitaly86
мне нужно распарсить xml содержаший элементы с ":"
Это?
Vitaly86
Дата: 19.01.2009 07:43:31
спасибо, как ни странно помогло :)
мне казалось что тут: xmlns:v="http://www/" обязательно нужно что-то осмысленное писать
оказалось что достаточно просто "заглушку сделать"
declare  @xml2 xml
     
set @xml2 = '<root xmlns:v="http://www/"> <t> ' +
            ' <n>1</n> ' +
            ' <v:date dt="2009-01-18">' +
            '   <v:time>18:05</v:time> '+
            '   <v:time>18:35</v:time> '+
            ' </v:date>'+
            ' </t> '+
            ' <t> ' +
            ' <n>2</n> ' +
            ' <v:date dt="2009-01-20">' +
            '   <v:time>20:05</v:time> '+
            '   <v:time>20:35</v:time> '+
            ' </v:date>'+
            ' </t> </root>'

declare @t table ( n varchar(10), vdate varchar(10), vtime varchar(10))

insert into @t 
select n
     , vdate
     , T2.Loc.value('text()[1]', 'varchar(50)') vtime
from (
select n
     , T2.Loc.value('@dt', 'varchar(50)') vdate
     , T2.Loc.query('declare namespace v="http://www/"; v:time') x
from ( 
      select T2.Loc.value('n[1]', 'varchar(50)') n
            , T2.Loc.query('declare namespace v="http://www/"; v:date') x
         from @xml2.nodes('/root/t') as T2(Loc)       
      ) t
        CROSS APPLY x.nodes('declare namespace v="http://www/"; /v:date' ) as T2(Loc)
   ) t
         CROSS APPLY x.nodes('declare namespace v="http://www/"; v:time' ) as T2(Loc)

остался вопрос:
можно ли ;WITH XMLNAMESPACES (DEFAULT '.....') использовать вместе с insert into @t
daw
Дата: 19.01.2009 08:11:11

> остался вопрос:
> можно ли ;WITH XMLNAMESPACES (DEFAULT '.....') использовать вместе с
> insert into @t

ну, собственно, default при разборе xml ни к чему. а вообще - можно и с
insert. к слову, а зачем так сложно-то делаете - так не проще?

;with xmlnamespaces('http://www/' as v)
insert into @t
select
   t.c.value('.', 'varchar(10)')
   , t.c.value('../.', 'varchar(10)')
   , t.c.value('../../n[1]', 'varchar(10)')
from @xml2.nodes('/root/t/v:date/v:time') t(c)

Posted via ActualForum NNTP Server 1.4

Vitaly86
Дата: 19.01.2009 08:23:00
daw, супер! спасибо.

так сложно потому что опыта нет совсем.
делаю по аналогии с тем что есть в примерах.
ощущения как в басне "мартышка и очки". вообщем то случайно получилось увидеть то что нужно :)


Всё таки можно ли данные из одного xml перелить в xml друго формата в ssis с помощью XML Task ?
Я правильно понял что он собственно для этого и создан.
Достаточно как то сформировать схемы. И можно имея на входе несколько xml разной структуры, на выходе получать xml одинаковой структуры?