web-dev-qa-db-fra.com

XPath pour récupérer la valeur SQL XML

Voici mon problème: à partir du XML suivant qui se trouve dans une colonne, je veux savoir si la valeur d'une variable avec le nom 'Enabled' est égale à 'Yes' étant donné un identifiant d'étape et un identifiant de composant.

'<xml>
  <box stepId="1">
    <components>
      <component id="2">
        <variables>
          <variable id="3" nom="Server" valeur="DEV1" />
          <variable id="4" nom="Enabled" valeur="Yes" />
        </variables>
      </component>
      <component id="3">
        <variables>
          <variable id="3" nom="Server" valeur="DEV1" />
          <variable id="4" nom="Enabled" valeur="No" />
        </variables>
      </component>
    </components>
  </box>
  <box stepId="2">
    <components>
      <component id="2">
        <variables>
          <variable id="3" nom="Server" valeur="DEV2" />
          <variable id="4" nom="Enabled" valeur="Yes" />
        </variables>
      </component>
      <component id="3">
        <variables>
          <variable id="3" nom="Server" valeur="DEV2" />
          <variable id="4" nom="Enabled" valeur="No" />
        </variables>
      </component>
    </components>
  </box>
</xml>'
22
joerage

Mise à jour

Ma recommandation serait de déchiqueter le XML en relations et de faire des recherches et des jointures sur la relation résultante, d'une manière orientée ensemble, plutôt que de la façon procédurale de rechercher des nœuds spécifiques dans le XML. Voici une requête XML simple qui détruit les nœuds et les attributs d'intérêt:

select x.value(N'../../../../@stepId', N'int') as StepID
  , x.value(N'../../@id', N'int') as ComponentID
  , x.value(N'@nom',N'nvarchar(100)') as Nom
  , x.value(N'@valeur', N'nvarchar(100)') as Valeur
from @x.nodes(N'/xml/box/components/component/variables/variable') t(x)

Cependant, si vous devez utiliser un XPath qui récupère exactement la valeur d'intérêt:

select x.value(N'@valeur', N'nvarchar(100)') as Valeur
from @x.nodes(N'/xml/box[@stepId=sql:variable("@stepID")]/
    components/component[@id = sql:variable("@componentID")]/
       variables/variable[@nom="Enabled"]') t(x)

Si le stepID et l'ID du composant sont des colonnes et non des variables, vous devez utiliser sql: column () au lieu de sql: variable dans les filtres XPath. Voir Liaison de données relationnelles à l'intérieur de données XML .

Et enfin si tout ce dont vous avez besoin est de vérifier l'existence, vous pouvez utiliser la méthode XML exist () :

select @x.exist(
  N'/xml/box[@stepId=sql:variable("@stepID")]/
    components/component[@id = sql:variable("@componentID")]/
      variables/variable[@nom="Enabled" and @valeur="Yes"]') 
36
Remus Rusanu

Je reviens toujours à cet article SQL Server 2005 XQuery et XML-DML - Partie 1 pour savoir comment utiliser les fonctionnalités XML dans SQL Server 2005.

Pour le savoir-faire XPath de base, je recommanderais le tutoriel W3Schools .

2
marc_s

Je pense que la requête xpath que vous voulez va quelque chose comme ceci:

/xml/box[@stepId="$stepId"]/components/component[@id="$componentId"]/variables/variable[@nom="Enabled" and @valeur="Yes"]

Cela devrait vous obtenir les variables nommées "Enabled" avec une valeur "Yes" pour les $ stepId et $ componentId spécifiés. Cela suppose que votre xml commence par une balise comme vous le montrez, et non

Si le truc SQL Server 2005 XPath est assez simple (je ne l'ai jamais utilisé), la requête ci-dessus devrait fonctionner. Sinon, quelqu'un d'autre devra peut-être vous aider.

2
Mike Cialowicz