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

Откуда:
Сообщений: 6
Добрый день! Коллеги помогите решить задачку:
<officialEmployees>
<k>LEADER</k>
<v>
<name>Иванов И.И.</name>
</v>
<k>ACCOUNTANT</k>
<v>
<name>Петров А.А.</name>
</v>
</officialEmployees>

Получал нужные мне поля name кодом:
xml.value('(/r/officialEmployees/v/name)[1]','nvarchar(100)')
и
xml.value('(/r/officialEmployees/v/name)[2]','nvarchar(100)')


Пока не оказалось, что ПО к базе которого я обращаюсь может менять эти блоки местам, т.е. сначала может быть LEADER за ним ACCOUNTANT, в какой то момент наоборот.
Собственно вопрос как привязаться не к порядку поля V, а к полю K?

Получить что то типа
xml.value('(/r/officialEmployees/k['LEADER']/v/name)[1]','nvarchar(100)')


Благодарен за любую помощь, подсказку!
11 янв 19, 13:10    [21782737]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4339
kjt, бить по голове тех, кто такую структуру хмль отдает предлагали?
11 янв 19, 13:13    [21782742]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
kjt
Member

Откуда:
Сообщений: 6
buser,
Разработчик этого ПО довольно серьезная компания ))
11 янв 19, 13:16    [21782750]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
msLex
Member

Откуда:
Сообщений: 5788
declare @x xml = 
'<r>
<officialEmployees>
<k>LEADER</k>
<v>
<name>Иванов И.И.</name>
</v>
<k>ACCOUNTANT</k>
<v>
<name>Петров А.А.</name>
</v>
</officialEmployees>
</r>
'




select 
	ACCOUNTANT = 
		case 'ACCOUNTANT' 
			when emp_1_title then emp_1 		
			when emp_2_title then emp_2
		end
	, LEADER = 
		case 'LEADER' 
			when emp_1_title then emp_1 		
			when emp_2_title then emp_2
		end
from (
select 
	emp_1 = @x.value('(/r/officialEmployees/v/name)[1]','nvarchar(100)')
	, emp_1_title = @x.value('(/r/officialEmployees/k)[1]','nvarchar(100)')
	, emp_2 =  @x.value('(/r/officialEmployees/v/name)[2]','nvarchar(100)')
	, emp_2_title =  @x.value('(/r/officialEmployees/k)[2]','nvarchar(100)')
) a 
11 янв 19, 13:20    [21782757]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4339
kjt
buser,
Разработчик этого ПО довольно серьезная компания ))

Ну намекните им... что времена EDI ушли...
11 янв 19, 13:34    [21782781]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4339
kjt, Retrieving the next or previous element node value in an Xml blob using XQuery
11 янв 19, 13:35    [21782783]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
kjt
Member

Откуда:
Сообщений: 6
msLex,

Спасибо!
11 янв 19, 13:51    [21782808]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
invm
Member

Откуда: Москва
Сообщений: 8438
Еще вариант
select
 a.k, b.n
from
 (select t.n.value('.', 'varchar(30)'), row_number() over (order by t.n) from @x.nodes('/r/officialEmployees/k') t(n)) a(k, rn) join
 (select t.n.value('.', 'varchar(30)'), row_number() over (order by t.n) from @x.nodes('/r/officialEmployees/v/name') t(n)) b(n, rn) on b.rn = a.rn;
11 янв 19, 14:57    [21782908]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7370
select 
  n.c.value('(for $s in ../v where $s >> . return($s))[1]', 'nvarchar(1000)') 
from @xml.nodes('/officialEmployees/k[.="LEADER"]') as n(c)

select 
  n.c.value('(for $s in ../v where $s >> . return($s))[1]', 'nvarchar(1000)') 
from @xml.nodes('/officialEmployees/k[.="ACCOUNTANT"]') as n(c)
11 янв 19, 15:09    [21782922]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4603
и наши 5 копеек:
declare
  @x xml=N'
<r>
  <officialEmployees>
    <k>LEADER</k>
    <v>
      <name>Иванов И.И.</name>
    </v>
    <k>ACCOUNTANT</k>
    <v>
      <name>Петров А.А.</name>
    </v>
  </officialEmployees>
</r>';
;with cte(position) as (
  select 'LEADER' union all select 'ACCOUNTANT'
)
select
  position, @x.value('(/r/officialEmployees/v[. >> (/r/officialEmployees/k[.=sql:column("position")])[1]]/name)[1]', 'varchar(100)')
from cte
11 янв 19, 15:41    [21782973]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4603
работали б в MSSQL-ном XQuery xpath-оси following/following-sibling - было бы в разы проще
11 янв 19, 15:42    [21782975]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
uaggster
Member

Откуда:
Сообщений: 540
Сон Веры Павловны
и наши 5 копеек:
declare
  @x xml=N'
<r>
  <officialEmployees>
    <k>LEADER</k>
    <v>
      <name>Иванов И.И.</name>
    </v>
    <k>ACCOUNTANT</k>
    <v>
      <name>Петров А.А.</name>
    </v>
  </officialEmployees>
</r>';
;with cte(position) as (
  select 'LEADER' union all select 'ACCOUNTANT'
)
select
  position, @x.value('(/r/officialEmployees/v[. >> (/r/officialEmployees/k[.=sql:column("position")])[1]]/name)[1]', 'varchar(100)')
from cte

Сон Веры Павловны, какое-нибудь вменяемое чтиво по этому делу можете посоветовать? В идеале - что-то типа М.Грабера. Понимание SQL.
11 янв 19, 16:02    [21782995]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг хмл  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4603
uaggster
Сон Веры Павловны, какое-нибудь вменяемое чтиво по этому делу можете посоветовать? В идеале - что-то типа М.Грабера. Понимание SQL.

Увы - всё, что знаю, почерпнуто из статей MSDN по XQuery, и из тем данного раздела форума. Собранного в одном месте не видел нигде. Разве что могу порекомендовать самоучители по XQuery общего характера (т.е. без привязки к специфике MSSQL) - типа https://www.w3schools.com/xml/xquery_intro.asp
11 янв 19, 16:25    [21783022]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить