T-SQL pour find un noeud dans une structure XML dynamic

Je voudrais savoir quelle est la bonne façon d'écrire une requête T-SQL pour returnner la valeur ou l'atsortingbut d'un nœud à partir d'une structure XML dynamic (multiniveau)?

Par exemple, si le XML ressemblait à ceci:

<xml> <a> <b>1</b> <c> <node atsortingb="ant">2</node> </c> </a> <a> <node atsortingb="bird">3</node> </a> <a> <b> <c> <node atsortingb="cat">4</node> </c> </b> </a> </xml> 

Quelle est la requête correcte pour renvoyer les valeurs et / ou les attributes pour le noeud ? Comme indiqué dans cet exemple, le noeud peut être à n'importe quel niveau …

J'ai essayé quelque chose comme ça (sans succès):

 SELECT node.value('node[1]', 'varchar(50)') AS node node.value('(node/@atsortingb)[1]', 'varchar(50)') AS atsortingb FROM xml.nodes('//xml/*') AS xml(node) 

EDIT: Merci StuartLC pour la réponse ci-dessous …

Basé sur l'aide ci-dessous, voici un exemple de travail qui contient également des namespaces:

 DECLARE @xml XML; SET @xml = ' <xml xmlns:abc="xyz"> <a> <b>1</b> <c> <abc:node atsortingb="ant">2</abc:node> </c> </a> <a> <abc:node atsortingb="bird">3</abc:node> </a> <a> <b> <c> <abc:node atsortingb="cat">4</abc:node> </c> </b> </a> </xml>'; ;WITH XMLNAMESPACES('xyz' AS ns) SELECT Nodes.node.value('.', 'varchar(50)') AS node, Nodes.node.value('(./@atsortingb)[1]', 'varchar(50)') AS atsortingb FROM @xml.nodes('//ns:node') AS Nodes(node); 

Ainsi:

 SELECT Nodes.node.value('.', 'varchar(50)') AS node, Nodes.node.value('(./@atsortingb)[1]', 'varchar(50)') AS atsortingb FROM @xml.nodes('//node') AS Nodes(node); 

Parce qu'il semble que vos éléments de node peuvent s'asseoir à n'importe quel endroit dans votre document xml , le // est utilisé pour searchr tous les éléments. Une fois que chaque node est trouvé, current() ou juste . peut être utilisé pour accéder à ce noeud.

SqlFiddle ici

Edit : Pour parsingr une colonne xml d'une table (par opposition à une variable @ml):

  SELECT Nodes.node.value('.', 'varchar(50)') AS node, Nodes.node.value('(./@atsortingb)[1]', 'varchar(50)') AS atsortingb FROM [TableWithXmlColumn] xyz cross apply xyz.XmlCol.nodes('//node') as Nodes(node); 

Si vous voulez les valeurs dans la même colonne, vous pouvez utiliser quelque chose comme ceci:

 select TXvalue('.', 'varchar(50)') from @XML.nodes('//*/text(), //@*') as T(X) 

SQL Fiddle