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