2010-09-13 4 views
0

J'ai le code XML ci-dessousTSQL sur XML (en utilisant 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> 

Comment puis-je obtenir l'aide TSQL le résultat suivant:

Col1 Col2 
0 34  
1 541 
2 255 
3 332 

Merci,

M

+0

Où le document XML est-il stocké? – annakata

Répondre

1

Cette expression 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;') 

Sortie:

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

Essayer de faire fonctionner comme ceci: select @ xml.query (» /myroot/scène/objet/ string-jointure (pour $ pos en (0 à max (*/count (*))) chaîne de retour -join (pour $ col in (1 à max (compte (*))) return if ($ pos = 0) puis concat ('Col', $ col) else * [$ col]/* [$ pos ], ''), ' ') ') Ne semble pas fonctionner – koumides

+0

@koumides: 'fn: count()' doit avoir un argument. La première invocation 'fn: max' compte le nombre maximum d'éléments dans une" colonne ". Donc ça doit être 'max (*/count (*))'. –

0

Voici mon approche XML noob.

Si vous faites confiance que l'enchaînement des éléments, et non pas les valeurs elles-mêmes coordonnées étant une séquence:

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 

Vous pouvez également écrit deux .nodes() et un JOIN (vous voyez l'idée).

Si la confiance avez-vous les coordonnées de numérotation à une séquence à partir de zéro:

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) 

Si vous faites confiance que la coordonnée de numérotation à une séquence, mais à partir d'une graine arbitraire:

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) 

Les chemins peuvent être abrégés:

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

Mais je ne sais pas la sagesse de cette toute façon.

//item/*/* peut probablement être rendu plus spécifique, de sorte qu'il ne comprend que coordinate et Value nœuds de bord, mais je ne connais pas la syntaxe.

Questions connexes