2010-09-13 4 views
0

У меня есть ниже XMLTSQL на XML (с помощью XQuery)

<myroot> 
<scene> 
<sceneId>983247</sceneId> 
<item> 
<coordinates> 
<coordinate>0</coordinate> 
<coordinate>1</coordinate> 
<coordinate>2</coordinate> 
<coordinate>3</coordinate> 
</coordinates> 
<Values> 
<Value>34</Value> 
<Value>541</Value> 
<Value>255</Value> 
<Value>332</Value> 
</Values> 
</item> 
</scene> 
</myroot> 

Как я могу получить с помощью TSQL следующий результат:

Col1 Col2 
0 34  
1 541 
2 255 
3 332 

Спасибо,

M

+0

Где хранится документ XML? – annakata

ответ

1

Эта экспрессия XPath 2.0:

/myroot/scene/item/ 
    string-join(for $pos in (0 to max(*/count(*))) 
       return string-join(for $col in (1 to max(count(*))) 
            return if ($pos=0) 
             then concat('Col',$col) 
             else *[$col]/*[$pos], 
            ' '), 
       '&#xA;') 

Выход:

Col1 Col2 
0 34 
1 541 
2 255 
3 332 
+1

Попытка запустить его так: выберите @ xml.query (» /myroot/сцена/элемент/ строка присоединиться (для $ поз в (0 до максимального значения (*/COUNT (*))) возврата строки -join (для $ col in (от 1 до max (count (*))) return if ($ pos = 0) then concat ('Col', $ col) else * [$ col]/* [$ pos ], ''), ' ') ') Не работает – koumides

+0

@koumides: 'fn: count()' должен иметь один аргумент. Первый вызов 'fn: max' подсчитывает максимальное количество элементов в некоторый« столбец ». Таким образом, это должно быть 'max (*/count (*))'. – 2010-09-13 16:59:53

0

Вот мой XML нуб подход.

Если доверять только элемент последовательности, а не координатные значения сами по себе быть последовательность:

select 
    coordinate = max(case when element = 'coordinate' then elemval end) 
, value  = max(case when element = 'Value' then elemval end) 
from (
    select 
    element = row.value('local-name(.)','varchar(32)') 
    , elemval = row.value('.','int') 
    , position = row.value('for $s in . return count(../*[. << $s]) + 1', 'int') 
    from @xml.nodes('/myroot/scene/item/*/*') a (row) 
) a 
group by position 

Альтернативно записывается в виде двух .nodes() и JOIN (вы получите идею).

Если вы доверяете координате нумерации последовательность, начиная с нуля:

select 
    coordinate = row.value('for $s in . return count(../*[. << $s]) + 1', 'int') 
      - 1 
, value  = row.value('.','int') 
from @xml.nodes('/myroot/scene/item/Values/*') a (row) 

Если доверять только координатой нумерации, чтобы быть последовательность, но из любого семени:

select 
    coordinate = row.value('for $s in . return count(../*[. << $s]) + 1', 'int') 
      + row.value('(/myroot/scene/item/coordinates/coordinate)[1]','int') 
      - 1 
, value  = row.value('.','int') 
from @xml.nodes('/myroot/scene/item/Values/*') a (row) 

Дорожки могут быть сокращены:

  • /myroot/scene/item/*/* ->//item/*/*
  • /myroot/scene/item/Values/* ->//Values/*
  • /myroot/scene/item/coordinates/coordinate ->//coordinate

Но я не знаю, мудрость этого в любом случае.

//item/*/* можно, скорее всего, сделать более конкретным, так что он включает только coordinate и Value краевые узлы, но я не знаю синтаксиса.

Смежные вопросы