Esempi di utilizzo della modalità PATHExamples: Using PATH Mode

Negli esempi seguenti viene illustrato l'utilizzo della modalità PATH nella creazione di codice XML da una query SELECT.The following examples illustrate the use of PATH mode in generating XML from a SELECT query. Molte di queste query vengono specificate sui documenti XML di istruzioni per la produzione di biciclette archiviate nella colonna Instructions della tabella ProductModel.Many of these queries are specified against the bicycle manufacturing instructions XML documents that are stored in the Instructions column of the ProductModel table.

Specifica di una query semplice in modalità PATHSpecifying a simple PATH mode query

La query seguente specifica una modalità FOR XML PATH.This query specifies a FOR XML PATH mode.

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

Il risultato seguente è codice XML incentrato sugli elementi in cui il valore di ogni colonna nel set di righe risultante viene inserito in un elemento.The following result is element-centric XML where each column value in the resulting rowset is wrapped in an element. Poiché la clausola SELECT non specifica alcun alias per i nomi delle colonne, i nomi degli elementi figlio generati sono gli stessi nomi di colonna corrispondenti nella clausola SELECT.Because the SELECT clause does not specify any aliases for the column names, the child element names generated are the same as the corresponding column names in the SELECT clause. Per ogni riga del set di righe viene aggiunto un tag <row>.For each row in the rowset a <row> tag is added.

<row>

<ProductModelID>122</ProductModelID>

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

</row>

<row>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</row>

Il risultato seguente corrisponde a quello della query in modalità RAW con l'opzione ELEMENTS specificata.The following result is the same as the RAW mode query with the ELEMENTS option specified. Restituisce codice XML incentrato sugli elementi con un elemento <row> predefinito per ogni riga del set di risultati.It returns element-centric XML with a default <row> element for each row in the result set.

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

È inoltre possibile specificare che il nome dell'elemento riga sovrascriva l'elemento <row> predefinito.You can optionally specify the row element name to overwrite the default <row>. Ad esempio, la query seguente restituisce l'elemento <ProductModel> per ogni riga del set di righe.For example, the following query returns the <ProductModel> element for each row in the rowset.

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

Il codice XML risultante avrà il nome dell'elemento riga specificato.The resulting XML will have a specified row element name.

<ProductModel>

<ProductModelID>122</ProductModelID>

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

</ProductModel>

<ProductModel>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</ProductModel>

Se viene specificata una stringa di lunghezza zero, l'elemento di wrapping non viene prodotto.If you specify a zero-length string, the wrapping element is not produced.

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

Risultato:This is the result:

<ProductModelID>122</ProductModelID>

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

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

Specifica di nomi di colonna in formato XPathSpecifying XPath-like column names

Nella query seguente il nome di colonna ProductModelID specificato inizia con "@" e non contiene una barra ("/").In the following query the ProductModelID column name specified starts with '@' and does not contain a slash mark ('/'). Nel codice XML risultante viene pertanto creato un attributo dell'elemento <row> con il valore di colonna corrispondente.Therefore, an attribute of the <row> element that has the corresponding column value is created in the resulting XML.

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

Risultato:This is the result:

< ProductModelData id="122">

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

</ ProductModelData >

< ProductModelData id="119">

<Name>Bike Wash</Name>

</ ProductModelData >

È possibile aggiungere un singolo elemento di livello principale specificando l'opzione root in FOR XML.You can add a single top-level element by specifying the root option in FOR XML.

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

Per creare una gerarchia è possibile includere una sintassi di tipo PATH.To generate a hierarchy, you can include PATH-like syntax. Ad esempio, modificando il nome della colonna da Name in "SomeChild/ModelName", si otterrà una struttura XML gerarchica, come illustrato nel risultato seguente:For example, change the column name for the Name column to "SomeChild/ModelName" and you will obtain XML with hierarchy, as shown in this result:

<Root>

<ProductModelData id="122">

<SomeChild>

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

</SomeChild>

</ProductModelData>

<ProductModelData id="119">

<SomeChild>

<ModelName>Bike Wash</ModelName>

</SomeChild>

</ProductModelData>

</Root>

Oltre all'ID del modello di prodotto e al nome, la query seguente consente di recuperare i percorsi delle relative istruzioni di produzione.Besides the product model ID and name, the following query retrieves the manufacturing instruction locations for the product model. Poiché la colonna Instructions è di tipo xml , per il recupero del percorso viene specificato il metodo query() del tipo di dati xml .Because the Instructions column is of xml type, the query() method of xml data type is specified to retrieve the location.

SELECT ProductModelID AS "@id",  
       Name,  
       Instructions.query('declare namespace MI="http://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  

Di seguito è riportato il risultato parziale.This is the partial result. Poiché la query specifica ManuInstr come nome di colonna, il wrapping del codice XML restituito dal metodo query() viene eseguito in un tag <ManuInstr> come illustrato di seguito:Because the query specifies ManuInstr as the column name, the XML returned by the query() method is wrapped in a <ManuInstr> tag as shown in the following:

<Root>

<ProductModelData id="7">

<Name>HL Touring Frame</Name>

<ManuInstr>

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

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

</MI:Location>

...

</ManuInstr>

</ProductModelData>

</Root>

Nella query FOR XML precedente può essere utile includere gli spazi dei nomi per gli elementi <Root> e <ProductModelData>.In the previous FOR XML query, you may want to include namespaces for the <Root> and <ProductModelData> elements. A questo scopo è necessario innanzitutto definire i prefissi per l'associazione degli spazi dei nomi tramite WITH XMLNAMESPACES e utilizzare tali prefissi nella query FOR XML.You can do this by first defining the prefix to namespace binding by using WITH XMLNAMESPACES and using prefixes in the FOR XML query. Per altre informazioni, vedere Aggiungere spazi dei nomi alle query con WITH XMLNAMESPACES.For more information, see Add Namespaces to Queries with WITH XMLNAMESPACES.

USE AdventureWorks2012;  
GO  
WITH XMLNAMESPACES (  
   'uri1' AS ns1,    
   'uri2' AS ns2,  
   'http://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  

Il prefisso MI è inoltre definito in WITH XMLNAMESPACES.Note that the MI prefix is also defined in the WITH XMLNAMESPACES. Di conseguenza, il metodo query() del tipo xml specificato non definisce il prefisso nel prologo della query.As a result, the query() method of the xml type specified does not define the prefix in the query prolog. Risultato:This is the result:

<ns1:root xmlns:MI="http://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="http://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>

Creazione di un elenco di valori mediante la modalità PATHGenerating a value list using PATH mode

La query successiva crea un elenco di valori di prodotti ID.For each product model, this query constructs a value list of product IDs. Per ogni ID prodotto la query crea inoltre elementi nidificati <ProductName>, come illustrato in questo frammento XML:For each product ID, the query also constructs <ProductName> nested elements, as shown in this XML fragment:

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

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

<ProductName>...</ProductName>

<ProductName>...</ProductName>

...

</ProductModelData>

La query che produce il codice XML desiderato è la seguente:This is the query that produces the XML you want:

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');  

Dalla query precedente si noti quanto segue:Note the following from the previous query:

  • La prima istruzione SELECT nidificata restituisce un elenco di ProductID utilizzando il nome di colonna data() .The first nested SELECT returns a list of ProductIDs by using data() as the column name. Poiché la query specifica una stringa vuota come nome dell'elemento riga in FOR XML PATH, non viene generato alcun elemento.Because the query specifies an empty string as the row element name in FOR XML PATH, no element is generated. L'elenco di valori viene invece assegnato all'attributo ProductID .Instead, the value list is assigned to the ProductID attribute.

  • La seconda istruzione SELECT nidificata recupera i nomi dei prodotti per quelli presenti nel modello del prodotto.The second nested SELECT retrieves product names for products in the product model. Genera elementi <ProductName> che vengono restituiti inseriti nell'elemento <ProductNames>, poiché la query specifica ProductNames come nome di colonna.It generates <ProductName> elements that are returned wrapped in the <ProductNames> element, because the query specifies ProductNames as the column name.

    Risultato parziale:This is the partial result:

    <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 sottoquery che crea i nomi di prodotto restituisce il risultato sotto forma di una stringa sostituita con entità e quindi aggiunta al codice XML.The subquery constructing the product names returns the result as a string that is entitized and then added to the XML. Se si aggiunge la direttiva TYPE, FOR XML PATH (''), type, la sottoquery restituisce il risultato come tipo xml e non viene eseguita la sostituzione con entità.If you add the type directive, FOR XML PATH (''), type, the subquery returns the result as xml type and no entitization occurs.

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');  

Aggiunta degli spazi dei nomi nel codice XML risultanteAdding namespaces in the resulting XML

Come descritto in Aggiungere spazi dei nomi alle query con WITH XMLNAMESPACES, è possibile usare WITH XMLNAMESPACES per includerli nelle query della modalità PATH.As described in Adding Namespaces Using WITH XMLNAMESPACES, you can use WITH XMLNAMESPACES to include namespaces in the PATH mode queries. Ad esempio, i nomi specificati nella clausola SELECT includono i prefissi degli spazi dei nomi.For example, names specified in the SELECT clause include namespace prefixes. La seguente query in modalità PATH crea codice XML con spazi dei nomi.The following PATH mode query constructs XML with namespaces.

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

L'attributo @xml:lang aggiunto all'elemento <English> viene definito nello spazio dei nomi xml predefinito.The @xml:lang attribute added to the <English> element is defined in the predefined xml namespace.

Risultato:This is the result:

<Translation>

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

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

</Translation>

La query seguente è simile a quella dell'esempio C, ma utilizza WITH XMLNAMESPACES per includere gli spazi dei nomi nel risultato XML.The following query is similar to example C, except that it uses WITH XMLNAMESPACES to include namespaces in the XML result. Per altre informazioni, vedere Aggiungere spazi dei nomi alle query con WITH XMLNAMESPACES.For more information, see Add Namespaces to Queries with 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');  

Risultato:This is the result:

<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>

Vedere ancheSee Also

Utilizzare la modalità PATH con FOR XMLUse PATH Mode with FOR XML