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

Откуда: Ленинградская обл.
Сообщений: 165
Здравствуйте!
Помогите составить запрос к XML.
Пример XML:
<root>
	<level1>
		<node attr1="1" attr2="Иванов"/>
		<node attr1="2" attr2="Сидоров">
			<node attr1="3" attr2="Петров"/>
			<node attr1="4" attr2="Семенов"/>
			<node attr1="5" attr2="Васильев"/>
		</node>
		<node attr1="6" attr2="Федоров"/>
		<node attr1="7" attr2="Алексеев"/>
		<node attr1="8" attr2="Третьяков"/>
		<node attr1="9" attr2="Поляков">
			<node attr1="10" attr2="Дмитриев"/>
			<node attr1="11" attr2="Ленин">
				<node attr1="12" attr2="Саган"/>
				<node attr1="13" attr2="Тайсон"/>
				<node attr1="14" attr2="Ньютон"/>
			</node>
			<node attr1="15" attr2="Галлей"/>
			<node attr1="16" attr2="Кэннон"/>
		</node>
		<node attr1="17" attr2="Эйнштейн"/>
		<node attr1="18" attr2="Фарадей"/>
		<node attr1="19" attr2="Максвелл"/>
	</level1>
</root>


Надо, чтобы на выходе получилось следующее:

attr1 attr2
===== ================
1 Иванов
2 Сидоров
3 Петров
4 Семенов
5 Васильев
6 Федоров
7 Алексеев
8 Третьяков
9 Поляков
10 Дмитриев
11 Ленин
12 Саган
13 Тайсон
14 Ньютон
15 Галлей
16 Кэннон
17 Эйнштейн
18 Фарадей
19 Максвелл

Причем, количество вложенных узлов, как и самих вложений неизвестно.
8 июл 16, 16:32    [19387136]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный обход XML узлов  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
declare @x xml = '<root>
	<level1>
		<node attr1="1" attr2="Иванов"/>
		<node attr1="2" attr2="Сидоров">
			<node attr1="3" attr2="Петров"/>
			<node attr1="4" attr2="Семенов"/>
			<node attr1="5" attr2="Васильев"/>
		</node>
		<node attr1="6" attr2="Федоров"/>
		<node attr1="7" attr2="Алексеев"/>
		<node attr1="8" attr2="Третьяков"/>
		<node attr1="9" attr2="Поляков">
			<node attr1="10" attr2="Дмитриев"/>
			<node attr1="11" attr2="Ленин">
				<node attr1="12" attr2="Саган"/>
				<node attr1="13" attr2="Тайсон"/>
				<node attr1="14" attr2="Ньютон"/>
			</node>
			<node attr1="15" attr2="Галлей"/>
			<node attr1="16" attr2="Кэннон"/>
		</node>
		<node attr1="17" attr2="Эйнштейн"/>
		<node attr1="18" attr2="Фарадей"/>
		<node attr1="19" attr2="Максвелл"/>
	</level1>
</root>';

select
 t.n.value('@attr1', 'int'),
 t.n.value('@attr2', 'varchar(50)');
from
 @x.nodes('//node') t(n)
8 июл 16, 16:37    [19387180]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный обход XML узлов  [new]
doos
Member

Откуда: Ленинградская обл.
Сообщений: 165
invm,

Спасибо большое! Работает. Нигде мне не попадался пример с двумя слэшами...
8 июл 16, 16:43    [19387216]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный обход XML узлов  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4539
doos, http://www.w3schools.com/xsl/xpath_syntax.asp
8 июл 16, 16:46    [19387243]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный обход XML узлов  [new]
doos
Member

Откуда: Ленинградская обл.
Сообщений: 165
buser,

узрел ))
8 июл 16, 16:49    [19387259]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный обход XML узлов  [new]
Konst_One
Member

Откуда:
Сообщений: 11623
немного расширю, может пригодится

select
 t.n.value('@attr1', 'int'),
 t.n.value('@attr2', 'varchar(50)'),
 t.n.query('count(node)').value('.', 'int') as childs,
 t.n.query('local-name(..)').value('.', 'varchar(10)') as parent
from
 @x.nodes('//node') t(n)
8 июл 16, 16:55    [19387291]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный обход XML узлов  [new]
doos
Member

Откуда: Ленинградская обл.
Сообщений: 165
Konst_One,

Ваще красотень )
8 июл 16, 16:58    [19387314]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный обход XML узлов  [new]
Konst_One
Member

Откуда:
Сообщений: 11623
ну и добьём:

select
 t.n.value('@attr1', 'int'),
 t.n.value('@attr2', 'varchar(50)'),
 t.n.query('count(node)').value('.', 'int') as childs,
 t.n.query('local-name(..)').value('.', 'varchar(10)') as parent,
 case when t.n.query('local-name(..)').value('.', 'varchar(10)') = 'node' 
      then t.n.query('data(../node[1]/@attr1)').value('.', 'int')
	  else 0
 end as parentid
from
 @x.nodes('//node') t(n)
8 июл 16, 17:14    [19387407]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить