web-dev-qa-db-fra.com

Comment obtenir un attribut particulier à partir d'un élément XML dans SQL Server

J'ai quelque chose comme le XML suivant dans une colonne d'une table:

<?xml version="1.0" encoding="utf-8"?>
<container>
  <param name="paramA" value="valueA" />
  <param name="paramB" value="valueB" />
  ...
</container>

J'essaie d'extraire la partie valueB du XML via TSQL

Jusqu'à présent, j'obtiens le bon nœud, mais maintenant je ne peux pas comprendre comment obtenir l'attribut.

select xmlCol.query('/container/param[@name="paramB"]') from LogTable

Je pense que je pourrais simplement ajouter une valeur/@ à la fin, mais SQL me dit que les attributs doivent faire partie d'un nœud. Je peux trouver beaucoup d'exemples pour sélectionner les attributs des nœuds enfants, mais rien sur les attributs frères (si c'est le bon terme).

Toute aide serait appréciée.

33
My Other Me

Essayez d'utiliser le .value fonction au lieu de .query:

SELECT 
  xmlCol.value('(/container/param[@name="paramB"]/@value)[1]', 'varchar(50)') 
FROM  
  LogTable

L'expression XPath peut potentiellement renvoyer une liste de nœuds, vous devez donc ajouter un [1] à cette liste potentielle pour indiquer à SQL Server d'utiliser la première de ces entrées (et oui - cette liste est basée sur 1 - pas sur base 0). En tant que deuxième paramètre, vous devez spécifier dans quel type la valeur doit être convertie - il suffit de deviner ici.

Marc

57
marc_s

En fonction de la structure réelle de votre xml, il peut être utile de mettre une vue dessus pour le rendre plus facile à utiliser en utilisant sql 'normal' par exemple

CREATE VIEW vwLogTable
AS
SELECT
    c.p.value('@name', 'varchar(10)') name,
    c.p.value('@value', 'varchar(10)') value
FROM
    LogTable
    CROSS APPLY x.nodes('/container/param') c(p)
GO


-- now you can get all values for paramB as...
SELECT value FROM vwLogTable WHERE name = 'paramB'
6
user189459