Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите реализовать функциональность  [new]
Добрыня
Guest
Дан xml
Как пройтись по всей его структуре и узнать значение всех атрибутов "Collus"?
Возможно, нужно каким-то образом заюзать XPATH...
16 июл 05, 16:54    [1710817]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Atez
Member

Откуда: Одесса
Сообщений: 15
Что-то типа этого, только я не до конца уверен...
...OPENXML (@idoc, 'descendant-or-self::*/@Value',1)...
16 июл 05, 17:00    [1710823]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
declare @idoc integer

exec sp_xml_preparedocument @idoc output,@xml

select t1.text from 
openxml(@idoc,'Root',2)t1
join openxml(@idoc,'/',1)t2 on (t1.parentid=t2.id)
where t2.localname = 'Collus'
18 июл 05, 06:05    [1711789]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
пардон происки copy->paste :)

declare @idoc integer

exec sp_xml_preparedocument @idoc output,@xml

select t1.text from 
openxmlopenxml(@idoc,'/',1)t1
join openxml(@idoc,'/',1)t2 on (t1.parentid=t2.id)
where t2.localname = 'Collus'


18 июл 05, 06:06    [1711790]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
Уважаемые проффесионалы, спасибо за помощь!
Но вот другая проблема, немогу понять почему так работает.
select t7.localname,t8.tre from
(select id tre,localname from openxml(@idoc,'/',1) where id in
(select t2.parentid from 
openxml(@idoc,'/',1)t1
join openxml(@idoc,'/',1)t2 on (t1.parentid=t2.id)
where t2.localname = 'Colname')
) t7
join
(select t1.text,t2.parentid tre from 
openxml(@idoc,'/',1)t1
join openxml(@idoc,'/',1)t2 on (t1.parentid=t2.id)
where t2.localname = 'Colname') 
t8 
on (t7.tre = t8.tre)
а вот так НЕ работает :(
select t7.localname,t8.abc from
(select id tre,localname from openxml(@idoc,'/',1) where id in
(select t2.parentid from 
openxml(@idoc,'/',1)t1
join openxml(@idoc,'/',1)t2 on (t1.parentid=t2.id)
where t2.localname = 'Colname')
) t7
join
(select t1.text,t2.parentid tre from 
openxml(@idoc,'/',1)t1
join openxml(@idoc,'/',1)t2 on (t1.parentid=t2.id)
where t2.localname = 'Colname') 
t8 
on (t7.tre = t8.tre)
Разница между первым и вторым примером в первом селекте (t8.abc вместо t8.tre)
Также не работает, если первый селект просто написать как t8.*
Выдаёт

Server: Msg 7399, Level 16, State 1, Line 27
OLE DB provider 'OpenXML' reported an error. The provider did not give any information about the error.
OLE DB error trace [OLE/DB Provider 'OpenXML' IRowset::RestartPosition returned 0x80004005: The provider did not give any information about the error.].

Да и ещё, чувствую что как-то можно оптимизировать этот запрос - а вот как не пойму... :(
18 июл 05, 14:46    [1713315]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
что-то типа такого
declare @idoc integer
exec sp_xml_preparedocument @idoc output ,N'<Root ID="0"><Level1 ID="1"/></Root>'

select * 
into #buffer
from openxml(@idoc,'/',1)t1

exec sp_xml_removedocument @idoc 

select t3.localname, t1.text
from #buffer t1
join #buffer t2 on (t1.parentid=t2.id)
join #buffer t3 on (t2.parentid=t3.id)
where t2.localname = 'ID'

drop table #buffer
18 июл 05, 16:33    [1713833]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
Я в шоке... Чудеса оптимизации...
Спасибо!!!
p.s. Получая такие ответы видишь ту границу, к которой нужно стремиться...
18 июл 05, 17:38    [1714062]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
А может чудеса безграничны и как то можно и этот код оптимизировать?
select t1.text,t2.parentid
from #buffer2 t1
join #buffer2 t2 on (t1.parentid=t2.id)
where t2.localname = 'Atr1') t5
join
(select t1.text,t2.parentid
from #buffer2 t1
join #buffer2 t2 on (t1.parentid=t2.id)
where t2.localname = 'Atr2') t6 on (t5.parentid = t6.parentid)
join
(select t1.text,t2.parentid
from #buffer2 t1
join #buffer2 t2 on (t1.parentid=t2.id)
where t2.localname = 'Atr3') t7 on (t5.parentid = t7.parentid) 
Или выше головы не прыгнешь? :)
20 июл 05, 10:35    [1719056]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
а что нужно то
может это
declare @idoc integer
exec sp_xml_preparedocument @idoc output ,
N'<Root Atr1="0" Atr2="00" Atr3="000"><Level1 Atr1="1" Atr2="11" Atr3="111"/></Root>'

select * 
into #buffer
from openxml(@idoc,'/',1)t1

exec sp_xml_removedocument @idoc 

select t1.localname, t2.localname, t3.text
from #buffer t1
join #buffer t2 on (t2.parentid = t1.id)
join #buffer t3 on (t3.parentid = t2.id)
where t2.localname in ('Atr1','Atr2','Atr3')

drop table #buffer
20 июл 05, 10:54    [1719175]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Toking
Member

Откуда: Ковров>>Королев
Сообщений: 234
А что за t5? У Вас этот запрос выполняется? Или не пробовали?

Что Вы хотите получить в итоге? Может не join, а Union?
20 июл 05, 10:57    [1719194]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
или может нуно это ? :)
declare @idoc integer
exec sp_xml_preparedocument @idoc output ,
N'<Root Atr1="0" Atr2="00" Atr3="000"><Level1 Atr1="1" Atr2="11"  Atr3="111"/></Root>'

select * 
into #buffer
from openxml(@idoc,'/',1)t1

exec sp_xml_removedocument @idoc 

select t1.localname, 
max(case when t2.localname='Atr1' then substring(t3.text,1,1000)  else null end) as Atr1,
max(case when t2.localname='Atr2' then substring(t3.text,1,1000) else null end) as Atr2,
max(case when t2.localname='Atr3' then substring(t3.text,1,1000) else null end) as Atr3
from #buffer t1
join #buffer t2 on (t2.parentid = t1.id)
join #buffer t3 on (t3.parentid = t2.id)
where t2.localname in ('Atr1','Atr2','Atr3')
group by t1.localname

drop table #buffer
20 июл 05, 10:59    [1719211]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
Ооо....Вы решили меня просто добить чудесами... :)
В идеальном случае нужно конечно что-то типа последнего - только там почему-то только одна запись выводится...
Нуно:получить список значений заданных атрибутов в любом элементе xml переменной
20 июл 05, 11:14    [1719316]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
вот для такого например
<xtron:GetMetaInfo_Param 
xmlns:xage="тра-та-та" 
xmlns:xsi="тра-та-та" 
xsi:schemaLocation="тра-та-та-та-та" 
MetatagMnemo="ACL" Entity="4C4180D4-4C40-4A77-8A49-78084A71A2DC">
<Params Quantity="2">
<Param Value="29F4CE79-C66C-4095-9A3B-0A92DEBF82E9" Name="AO" Condition="="/>
<Param Value="77777777-7777-7777-7777-777777777777" Name="PO" Condition=">"/>
</Params>
</xtron:GetMetaInfo_Param>
20 июл 05, 11:18    [1719344]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
declare @idoc integer
exec sp_xml_preparedocument @idoc output ,
N'<Root Atr1="0" Atr2="00" Atr3="000">
<Level1 Atr1="1" Atr2="11"  Atr3="111">
<Level2 Atr2="55"/>
</Level1>
<Level1 Atr1="2" Atr2="22"  Atr3="333"/>
</Root>'

select * 
into #buffer
from openxml(@idoc,'/',1)t1

exec sp_xml_removedocument @idoc 

select t1.localname, 
max(case when t2.localname='Atr1' then substring(t3.text,1,1000)  else null end) as Atr1,
max(case when t2.localname='Atr2' then substring(t3.text,1,1000) else null end) as Atr2,
max(case when t2.localname='Atr3' then substring(t3.text,1,1000) else null end) as Atr3
from #buffer t1
join #buffer t2 on (t2.parentid = t1.id)
join #buffer t3 on (t3.parentid = t2.id)
where t2.localname in ('Atr1','Atr2','Atr3')
group by t1.localname, t1.id
order by t1.id

drop table #buffer



20 июл 05, 11:24    [1719387]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
declare @idoc integer
exec sp_xml_preparedocument @idoc output ,
N'<xtron
xmlns:xage="тра-та-та" 
xmlns:xsi="тра-та-та" 
xsi:schemaLocation="тра-та-та-та-та" 
MetatagMnemo="ACL" Entity="4C4180D4-4C40-4A77-8A49-78084A71A2DC">
<Params Quantity="2">
<Param Value="29F4CE79-C66C-4095-9A3B-0A92DEBF82E9" Name="AO" Condition="="/>
<Param Value="77777777-7777-7777-7777-777777777777" Name="PO" Condition=">"/>
</Params>
</xtron>'



select * 
into #buffer
from openxml(@idoc,'/',1)t1

exec sp_xml_removedocument @idoc 

select t1.localname, 
max(case when t2.localname='Value' then substring(t3.text,1,1000)  else null end) as Value,
max(case when t2.localname='Name' then substring(t3.text,1,1000) else null end) as Name,
max(case when t2.localname='Condition' then substring(t3.text,1,1000) else null end) as Condition
from #buffer t1
join #buffer t2 on (t2.parentid = t1.id)
join #buffer t3 on (t3.parentid = t2.id)
where t2.localname in ('Value','Name','Condition')
group by t1.localname, t1.id
order by t1.id

drop table #buffer

20 июл 05, 11:33    [1719457]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
о чудо... оно работает......
Предлагаю чтоли из этого faq сделать.
20 июл 05, 11:39    [1719501]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Glory
Member

Откуда:
Сообщений: 104760
А чего так сложно-то ?

declare @idoc integer
exec sp_xml_preparedocument @idoc output ,
N'<xtron
xmlns:xage="тра-та-та" 
xmlns:xsi="тра-та-та" 
xsi:schemaLocation="тра-та-та-та-та" 
MetatagMnemo="ACL" Entity="4C4180D4-4C40-4A77-8A49-78084A71A2DC">
<Params Quantity="2">
<Param Value="29F4CE79-C66C-4095-9A3B-0A92DEBF82E9" Name="AO" Condition="="/>
<Param Value="77777777-7777-7777-7777-777777777777" Name="PO" Condition=">"/>
</Params>
</xtron>'



select * 
from openxml(@idoc,'/xtron/Params/Param',1)
WITH 
(
  Value varchar(20),
  Name   varchar(20),
  Condition   varchar(20)
) 

exec sp_xml_removedocument @idoc 
20 июл 05, 14:57    [1720799]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
Так как структура может быть произвольной - и поэтому
openxml(@idoc,'/xtron/Params/Param',1)
неприменимо.
В другом файле может не быть такой структуры: /xtron/Params/Param
20 июл 05, 15:20    [1720986]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Glory
Member

Откуда:
Сообщений: 104760
Так как структура может быть произвольной - и поэтому
Хм - универсальный конвертор всего во все ?
20 июл 05, 15:29    [1721043]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
Нет, просто универсальная процедура извлечения метаданных.
20 июл 05, 16:05    [1721345]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Glory
Member

Откуда:
Сообщений: 104760
Добрыня
Нет, просто универсальная процедура извлечения метаданных.

По-моему, для правильного решения такой задачи сам XML должен содержать метаданные
20 июл 05, 16:08    [1721362]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
Не совсем понял что Вы имеете ввиду.
После отработки процедуры клиенская часть разумеется заполнит структуру метаданными.
Здесь же мы ищем данные, которые необходимо вернуть клиенту.
А вообще ( в более глобальном плане), это один из вариантов проектирования системы работы с различными метаданными, к которой я, честно говоря отношусь скептически...
20 июл 05, 16:25    [1721437]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Glory
Member

Откуда:
Сообщений: 104760
Добрыня
Не совсем понял что Вы имеете ввиду.

Я имею ввиду, что валидный XML выглядит так
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' 
xmlns:dt='urn:schemas-microsoft-com:xml:datatypes' 
xmlns:rs='urn:schemas-microsoft-com:rowset' 
xmlns:z='#RowsetSchema'> 
<s:Schema id='RowsetSchema'> 
<s:ElementType name='row' content='eltOnly' rs:updatable='true'> 
<s:AttributeType name='ObID' rs:number='1' rs:nullable='true' rs:writeunknown='true' rs:basecatalog='AN' 
rs:basetable='#tmp' rs:basecolumn='ObID'> 
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true'/> 
</s:AttributeType> 
<s:AttributeType name='subjectID' rs:number='2' rs:nullable='true' rs:writeunknown='true' rs:basecatalog='AN' 
rs:basetable='#tmp' rs:basecolumn='subjectID'> 
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true'/> 
</s:AttributeType> 
<s:extends type='rs:rowbase'/> 
</s:ElementType> 
</s:Schema> 
<rs:data> 
<z:row ObID='3' subjectID='7'/> 
<z:row ObID='4' subjectID='7'/> 
<z:row ObID='5' subjectID='6'/> 
<z:row ObID='6' subjectID='6'/> 
<z:row ObID='7' subjectID='18'/> 
</rs:data> 
</xml> 

Поэтому не надо самому догадывася что он содержит,а что не содержит
20 июл 05, 16:31    [1721477]     Ответить | Цитировать Сообщить модератору
 Re: Помогите реализовать функциональность  [new]
Добрыня
Guest
Тут как раз другая проблема -
необходимо догадаться что он содержит...
Задан xml произвольной структуры (известо только несколько имён атрибутов ( например имя столбца в котором храниться значение).
Требуется найти все значения из базы зная названия столбцов.
20 июл 05, 16:45    [1721556]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить