Partager via


Exemples : utilisation du mode PATH

Les exemples suivants illustrent l’utilisation du mode PATH pour générer du code XML à partir d’une requête SELECT. La plupart de ces requêtes sont spécifiées par rapport aux documents XML des instructions de fabrication de vélos qui sont stockés dans la colonne Instructions de la table ProductModel.

Spécification d’une requête en mode PATH simple

Cette requête spécifie un mode FOR XML PATH.

USE AdventureWorks2012;  
GO  
SELECT   
       ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML PATH;  
GO  

Le résultat suivant est le code XML centré sur les éléments où chaque valeur de colonne dans l’ensemble de lignes résultant est encapsulée dans un élément. Étant donné que la SELECT clause ne spécifie pas d’alias pour les noms de colonnes, les noms d’éléments enfants générés sont identiques aux noms de colonnes correspondants dans la SELECT clause. Pour chaque ligne de l’ensemble de lignes, une <row> balise est ajoutée.

<row>

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

</row>

<row>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</row>

Le résultat suivant est identique à la requête en RAW mode avec l’option ELEMENTS spécifiée. Elle retourne le code XML centré sur l’élément avec un élément par défaut <row> pour chaque ligne du jeu de résultats.

USE AdventureWorks2012;  
GO  
SELECT ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML RAW, ELEMENTS;  

Vous pouvez éventuellement spécifier le nom de l’élément de ligne pour remplacer la valeur par défaut <row>. Par exemple, la requête suivante retourne l’élément <ProductModel> pour chaque ligne de l’ensemble de lignes.

USE AdventureWorks2012;  
GO  
SELECT ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 or ProductModelID=119  
FOR XML PATH ('ProductModel');  
GO  

Le code XML résultant aura un nom d’élément de ligne spécifié.

<ProductModel>

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

</ProductModel>

<ProductModel>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</ProductModel>

Si vous spécifiez une chaîne de longueur nulle, l’élément d’habillage n’est pas généré.

USE AdventureWorks2012;  
GO  
SELECT ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML PATH ('');  
GO  

Voici le résultat obtenu :

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

Spécification des noms de colonnes de type XPath

Dans la requête suivante, le ProductModelID nom de colonne spécifié commence par « @ » et ne contient pas de barre oblique ('/'). Par conséquent, un attribut de l’élément <row> qui a la valeur de colonne correspondante est créé dans le code XML résultant.

USE AdventureWorks2012;  
GO  
SELECT ProductModelID AS "@id",  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML PATH ('ProductModelData');  
GO  

Voici le résultat obtenu :

< ProductModelData id="122">

<Name>All-Purpose Bike Stand</Name>

</ ProductModelData >

< ProductModelData id="119">

<Name>Bike Wash</Name>

</ ProductModelData >

Vous pouvez ajouter un seul élément de niveau supérieur en spécifiant l’option root dans FOR XML.

SELECT ProductModelID AS "@id",  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 or ProductModelID=119  
FOR XML PATH ('ProductModelData'), root ('Root');  
GO  

Pour générer une hiérarchie, vous pouvez inclure une syntaxe similaire à PATH. Par exemple, remplacez le nom de colonne de la Name colonne par « SomeChild/ModelName » et vous obtiendrez du code XML avec une hiérarchie, comme indiqué dans ce résultat :

<Root>

<ProductModelData id="122">

<SomeChild>

<ModelName>All-Purpose Bike Stand</ModelName>

</SomeChild>

</ProductModelData>

<ProductModelData id="119">

<SomeChild>

<ModelName>Bike Wash</ModelName>

</SomeChild>

</ProductModelData>

</Root>

Outre l’ID et le nom du modèle de produit, la requête suivante récupère les emplacements d’instructions de fabrication pour le modèle de produit. Étant donné que la colonne Instructions est de xml type, la query() méthode de type de xml données est spécifiée pour récupérer l’emplacement.

SELECT ProductModelID AS "@id",  
       Name,  
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
                /MI:root/MI:Location   
              ') AS ManuInstr  
FROM Production.ProductModel  
WHERE ProductModelID = 7  
FOR XML PATH ('ProductModelData'), root ('Root');  
GO  

Le résultat partiel est le suivant. Étant donné que la requête spécifie ManuInstr comme nom de colonne, le code XML retourné par la query() méthode est encapsulé dans une <ManuInstr> balise, comme indiqué dans les éléments suivants :

<Root>

<ProductModelData id="7">

<Name>HL Touring Frame</Name>

<ManuInstr>

<MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"

<MI:step>...</MI:step>...

</MI:Location>

...

</ManuInstr>

</ProductModelData>

</Root>

Dans la requête FOR XML précédente, vous pouvez inclure des espaces de noms pour les éléments et><ProductModelDatales <Root> éléments. Pour ce faire, vous pouvez d’abord définir le préfixe à la liaison d’espace de noms à l’aide de WITH XMLNAMESPACES et d’utiliser des préfixes dans la requête FOR XML. Pour plus d’informations, consultez Ajouter des espaces de noms aux requêtes avec WITH XMLNAMESPACES.

USE AdventureWorks2012;  
GO  
WITH XMLNAMESPACES (  
   'uri1' AS ns1,    
   'uri2' AS ns2,  
   'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' as MI)  
SELECT ProductModelID AS "ns1:ProductModelID",  
       Name           AS "ns1:Name",  
       Instructions.query('  
                /MI:root/MI:Location   
              ')   
FROM Production.ProductModel  
WHERE ProductModelID=7  
FOR XML PATH ('ns2:ProductInfo'), root('ns1:root');  
GO  

Notez que le MI préfixe est également défini dans le WITH XMLNAMESPACES. Par conséquent, la query() méthode du xml type spécifié ne définit pas le préfixe dans le prolog de requête. Voici le résultat obtenu :

<ns1:root xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" xmlns="uri2" xmlns:ns2="uri2" xmlns:ns1="uri1">

<ns2:ProductInfo>

<ns1:ProductModelID>7</ns1:ProductModelID>

<ns1:Name>HL Touring Frame</ns1:Name>

<MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"

LaborHours="2.5" LotSize="100" MachineHours="3" SetupHours="0.5" LocationID="10" xmlns="">

<MI:step>

Insert <MI:material>aluminum sheet MS-2341</MI:material> into the <MI:tool>T-85A framing tool</MI:tool>.

</MI:step>

...

</MI:Location>

...

</ns2:ProductInfo>

</ns1:root>

Génération d’une liste de valeurs à l’aide du mode PATH

Pour chaque modèle de produit, cette requête construit une liste de valeurs d’ID de produit. Pour chaque ID de produit, la requête construit également des éléments imbriqués <ProductName> , comme indiqué dans ce fragment XML :

<ProductModelData ProductModelID="7" ProductModelName="..."

ProductIDs="product id list in the product model" >

<ProductName>...</ProductName>

<ProductName>...</ProductName>

...

</ProductModelData>

Il s’agit de la requête qui produit le code XML souhaité :

USE AdventureWorks2012;  
GO  
SELECT ProductModelID     AS "@ProductModelID",  
       Name               S "@ProductModelName",  
      (SELECT ProductID AS "data()"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH ('')) S "@ProductIDs",  
       (SELECT Name AS "ProductName"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
        FOR XML PATH ('')) as "ProductNames"  
FROM   Production.ProductModel  
WHERE  ProductModelID= 7 or ProductModelID=9  
FOR XML PATH('ProductModelData');  

Notez les points suivants dans la requête précédente :

  • Le premier imbriqué SELECT retourne une liste de ProductIDs à l’aide de data() comme nom de colonne. Étant donné que la requête spécifie une chaîne vide comme nom d’élément de ligne dans FOR XML PATH, aucun élément n’est généré. Au lieu de cela, la liste de valeurs est affectée à l’attribut ProductID .

  • Le deuxième imbriqué SELECT récupère les noms de produits des produits dans le modèle de produit. Elle génère des éléments retournés encapsulés dans l’élément<ProductNames>, car la requête spécifie ProductNames comme nom de colonne.<ProductName>

Voici le résultat partiel :

<ProductModelData PId="7"

ProductModelName="HL Touring Frame"

ProductIDs="885 887 ...">

<ProductNames>

<ProductName>HL Touring Frame - Yellow, 60</ProductName>

<ProductName>HL Touring Frame - Yellow, 46</ProductName></ProductNames>

...

</ProductModelData>

<ProductModelData PId="9"

ProductModelName="LL Road Frame"

ProductIDs="722 723 724 ...">

<ProductNames>

<ProductName>LL Road Frame - Black, 58</ProductName>

<ProductName>LL Road Frame - Black, 60</ProductName>

<ProductName>LL Road Frame - Black, 62</ProductName>

...

</ProductNames>

</ProductModelData>

La sous-requête qui construit les noms de produit retourne le résultat sous forme de chaîne qui est entitisée, puis ajoutée au code XML. Si vous ajoutez la directive de type, FOR XML PATH (''), type la sous-requête retourne le résultat en tant que type xml et aucune entitisation ne se produit.

USE AdventureWorks2012;  
GO  
SELECT ProductModelID AS "@ProductModelID",  
      Name AS "@ProductModelName",  
      (SELECT ProductID AS "data()"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH ('')  
       ) AS "@ProductIDs",  
       (  
       SELECT Name AS "ProductName"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH (''), type  
       ) AS "ProductNames"  
  
FROM Production.ProductModel  
WHERE ProductModelID= 7 OR ProductModelID=9  
FOR XML PATH('ProductModelData');  

Ajout d’espaces de noms dans le code XML résultant

Comme décrit dans Ajout d’espaces de noms à l’aide de WITH XMLNAMESPACES, vous pouvez utiliser WITH XMLNAMESPACES pour inclure des espaces de noms dans les requêtes en mode PATH. Par exemple, les noms spécifiés dans la clause SELECT incluent des préfixes d’espace de noms. La requête en mode suivant PATH construit du code XML avec des espaces de noms.

SELECT 'en'    as "English/@xml:lang",  
       'food'  as "English",  
       'ger'   as "German/@xml:lang",  
       'Essen' as "German"  
FOR XML PATH ('Translation')  
GO  

L’attribut @xml:lang ajouté à l’élément <English> est défini dans l’espace de noms xml prédéfini.

Voici le résultat obtenu :

<Translation>

<English xml:lang="en">food</English>

<German xml:lang="ger">Essen</German>

</Translation>

La requête suivante est similaire à l’exemple C, sauf qu’elle utilise WITH XMLNAMESPACES pour inclure des espaces de noms dans le résultat XML. Pour plus d’informations, consultez Ajouter des espaces de noms aux requêtes avec WITH XMLNAMESPACES.

USE AdventureWorks2012;  
GO  
WITH XMLNAMESPACES ('uri1' AS ns1,  DEFAULT 'uri2')  
SELECT ProductModelID AS "@ns1:ProductModelID",  
      Name AS "@ns1:ProductModelName",  
      (SELECT ProductID AS "data()"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH ('')  
       ) AS "@ns1:ProductIDs",  
       (  
       SELECT ProductID AS "@ns1:ProductID",   
              Name AS "@ns1:ProductName"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH , type   
       ) AS "ns1:ProductNames"  
FROM Production.ProductModel  
WHERE ProductModelID= 7 OR ProductModelID=9  
FOR XML PATH('ProductModelData'), root('root');  

Voici le résultat obtenu :

<root xmlns="uri2" xmlns:ns1="uri1">

<ProductModelData ns1:ProductModelID="7" ns1:ProductModelName="HL Touring Frame" ns1:ProductIDs="885 887 888 889 890 891 892 893">

<ns1:ProductNames>

<row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="885" ns1:ProductName="HL Touring Frame - Yellow, 60" />

<row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="887" ns1:ProductName="HL Touring Frame - Yellow, 46" />

...

</ns1:ProductNames>

</ProductModelData>

<ProductModelData ns1:ProductModelID="9" ns1:ProductModelName="LL Road Frame" ns1:ProductIDs="722 723 724 725 726 727 728 729 730 736 737 738">

<ns1:ProductNames>

<row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="722" ns1:ProductName="LL Road Frame - Black, 58" />

...

</ns1:ProductNames>

</ProductModelData>

</root>

Voir aussi

Utiliser le mode PATH avec FOR XML