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

Откуда: Киев (Альба)
Сообщений: 66
Всем привет. Разбираю произвольный текст на слова, пытаясь попрактиковаться в XML.

declare 
	@s nvarchar (max),
	@xml xml

Select @s = 
	(
	Select 
		'One  two th>ree '+CHAR(13) + CHAR (10) +
		'four five six'+CHAR(13) + CHAR (10) +
		'Seven eight'
	)

Print @s 




Select @s = REPLACE(@s,CHAR(13)+Char(10),' '+Char(13)+char(10))
Select @s = '<Child>'''+REPLACE(@s,' ',N' ''</Child><Child>''')+'''</Child>'

--Select @s

Select 
@xml = 
	convert(xml,	
	'<Root>' + 
	 REPLACE(@s, '<Child>''' + CHAR(13)+CHAR(10),'</Root><Root><Child>''')
	 +'</Root>'	 
	)

--Select @xml


Select
	Word = Rtrim(SUBSTRING(Word,2,Len(Word)-2)),
	StringNumber,
	WordNumber = ROW_NUMBER() over (Partition by StringNumber order by WordNumber)
from
	(
	SELECT 
		t.c.value('count(for $s in(/Root) where $s << . return(.))', 'int') as StringNumber,
		t.c.value('count(for $s in(/Root/Child) where $s << . return(.))', 'int') as WordNumber,
		t.c.value('.', 'varchar(max)') Word
	FROM @xml.nodes('//Child') AS t(c)
	) a
where Rtrim(SUBSTRING(Word,2,Len(Word)-2))<>''


Подскажите:
а) Можно ли уйти красивым способом от экранирования в кавычки каждого слова - пытаюсь обойти спецсимволы.
б) Как правильно пронумеровать строки внутри ноды, получилось сделать только сплошную нумерацию

t.c.value('count(for $s in(/Root/Child) where $s << . return(.))', 'int') as WordNumber
7 ноя 16, 19:06    [19867170]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с XML  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1451
VGalamakh,

можно так и генерить динамически числовую последовательность :( очень жалко что XQuery в сиквеле не поддерживает for to

declare 
       @s nvarchar (max),
	   @xml xml

Select @s = 'One  two th>ree '+CHAR(13) + CHAR (10) + 'four five six'+CHAR(13) + CHAR (10) + 'Seven eight'

set @s = replace(@s, char(13) + char(10), char(32))
set @xml = cast('<node>' + replace(@s, char(32), '</node><node>') + '</node>' as xml)

select @xml =  @xml.query('for $i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)		  
                return <node id="{$i}">{(/node[position() = $i]/text())}</node>')

select row_number() over (order by id),
       [text]
from (
      select
            T.c.value('./@id', 'int'),
            T.c.value('./text()[1]', 'varchar(255)')
      from @xml.nodes('/node') T(c)
      where c.exist('./text()') = 1
	  ) T([id], [text])
7 ноя 16, 23:39    [19868122]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с XML  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
VGalamakh
Подскажите:
а) Можно ли уйти красивым способом от экранирования в кавычки каждого слова - пытаюсь обойти спецсимволы.
б) Как правильно пронумеровать строки внутри ноды, получилось сделать только сплошную нумерацию
declare 
 @s nvarchar (max),
 @xml xml;

Select @s = 
		'One  two th>ree '+CHAR(13) + CHAR (10) +
		'four five six'+CHAR(13) + CHAR (10) +
		'Seven eight'+CHAR(13) + CHAR (10);

select
 @xml = '<line><word>' + replace(replace(replace(cast(cast('' as xml).query('sql:variable("@s")') as varchar(max)), ' ', '</word><word>'), '&#x0D;', '</word></line><line><word>'), char(10), '') + '</word></line>';

with l as
(
 select
  t.n.query('.') as line,
  row_number() over (order by (select 1)) as ln
 from
  @xml.nodes('/line') t(n)
)
select
 l.ln,
 row_number() over (partition by l.ln order by (select 1)) as wn,
 t.n.value('.', 'varchar(100)') as word
from
 l cross apply
 l.line.nodes('/line/word[text()]') t(n);
8 ноя 16, 12:07    [19869540]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с XML  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
invm,

select
@xml = REPLACE( CONVERT( VARCHAR(MAX), (
SELECT
@s
FOR
XML PATH( 'word' ), ROOT( 'line' )
) ), ' ', '</word><word>' )
;
8 ноя 16, 12:33    [19869700]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с XML  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
Руслан Дамирович
Фигню написал

Непонятно, что вы пытаетесь решить, но очень похоже на
iap
Lexa_V,
в последнее время модно стало делать это с помощью XML (поиск).
А можно и по-старинке: Функция, которая делит строку на слова
И в местном FAQ, по-моему, есть.
8 ноя 16, 12:38    [19869747]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить