Aggiungere spazi dei nomi alle query con WITH XMLNAMESPACESAdd Namespaces to Queries with WITH XMLNAMESPACES

La clausolaWITH XMLNAMESPACES (Transact-SQL) offre il supporto dell'URI dello spazio dei nomi nel modo seguente:WITH XMLNAMESPACES (Transact-SQL) provides namespace URI support in the following way:

Utilizzo di WITH XMLNAMESPACES nelle query FOR XMLUsing WITH XMLNAMESPACES in the FOR XML Queries

WITH XMLNAMESPACES consente di includere gli spazi dei nomi XML nelle query FOR XML.WITH XMLNAMESPACES lets you include XML namespaces in FOR XML queries. Si consideri, ad esempio, la query FOR XML seguente:For example, consider the following FOR XML query:

SELECT ProductID, Name, Color  
FROM   Production.Product  
WHERE  ProductID=316 or ProductID=317  
FOR XML RAW  

Risultato:This is the result:

<row ProductID="316" Name="Blade" />  
<row ProductID="317" Name="LL Crankarm" Color="Black" />  

Per aggiungere spazi dei nomi al codice XML creato dalla query FOR XML, specificare innanzitutto il mapping tra il prefisso dello spazio dei nomi e l'URI utilizzando la clausola WITH NAMESPACES.To add namespaces to the XML constructed by the FOR XML query, first specify the namespace prefix to URI mappings by using the WITH NAMESPACES clause. Utilizzare quindi i prefissi dello spazio dei nomi per specificare i nomi nella query, come illustrato nella query modificata seguente.Then, use the namespace prefixes in specifying the names in the query as shown in the following modified query. Si noti che la clausola WITH XMLNAMESPACES specifica il mapping tra il prefisso dello spazio dei nomi (ns1) e l'URI (uri).Note that the WITH XMLNAMESPACES clause specifies the namespace prefix (ns1) to URI (uri) mapping. Il prefisso ns1 viene quindi utilizzato per specificare i nomi degli elementi e degli attributi che devono essere creati per la query FOR XML.The ns1 prefix is then used in specifying the element and attribute names to be constructed by the FOR XML query.

WITH XMLNAMESPACES ('uri' as ns1)  
SELECT ProductID as 'ns1:ProductID',  
       Name      as 'ns1:Name',   
       Color     as 'ns1:Color'  
FROM Production.Product  
WHERE ProductID=316 or ProductID=317  
FOR XML RAW ('ns1:Prod'), ELEMENTS  

Il risultato XML include i prefissi dello spazio dei nomi seguenti:The XML result includes the namespace prefixes:

<ns1:Prod xmlns:ns1="uri">  
  <ns1:ProductID>316</ns1:ProductID>  
  <ns1:Name>Blade</ns1:Name>  
</ns1:Prod>  
<ns1:Prod xmlns:ns1="uri">  
  <ns1:ProductID>317</ns1:ProductID>  
  <ns1:Name>LL Crankarm</ns1:Name>  
  <ns1:Color>Black</ns1:Color>  
</ns1:Prod>  

Per la clausola WITH XMLNAMESPACES sono valide le osservazioni seguenti:The following applies to the WITH XMLNAMESPACES clause:

  • La clausola è supportata solo nelle modalità RAW, AUTO e PATH delle query FOR XML.It is supported only on the RAW, AUTO, and PATH modes of the FOR XML queries. La modalità EXPLICIT non è supportata.The EXPLICIT mode is not supported.

  • La clausola influisce solo sui prefissi dello spazio dei nomi delle query FOR XML e sui metodi con tipo di dati xml , ma non sul parser XML.It only affects the namespace prefixes of FOR XML queries and the xml data type methods, but not the XML parser. Ad esempio, la query seguente restituisce un errore perché nel documento XML non è disponibile una dichiarazione dello spazio dei nomi per il prefisso myNS.For example, the following query returns an error, because the XML document has no namespace declaration for the myNS prefix.

  • Se si utilizza una clausola WITH XMLNAMESPACES, non è possibile utilizzare le direttive FOR XML, ovvero XMLSCHEMA e XMLDATA.The FOR XML directives, XMLSCHEMA and XMLDATA cannot be used when a WITH XMLNAMESPACES clause is being used.

    CREATE TABLE T (x xml)  
    go  
    WITH XMLNAMESPACES ('http://abc' as myNS )  
    INSERT INTO T VALUES('<myNS:root/>')  
    

Utilizzo della direttiva XSINILUsing the XSINIL Directive

Se si utilizza la direttiva ELEMENTS XSINIL, non è possibile definire il prefisso xsi nella clausola WITH XMLNAMESPACES.You cannot define the xsi prefix in the WITH XMLNAMESPACES clause if you are using the ELEMENTS XSINIL directive. Questo prefisso viene infatti aggiunto automaticamente quando si utilizza ELEMENTS XSINIL.Instead, it is added automatically when you use ELEMENTS XSINIL. La query seguente usa ELEMENTS XSINIL che genera codice XML incentrato sugli elementi nel quale viene eseguito il mapping dei valori Null a elementi con l'attributo xsi:nil impostato su True.The following query uses ELEMENTS XSINIL that generates element-centric XML where null values are mapped to elements that have the xsi:nil attribute set to True.

WITH XMLNAMESPACES ('uri' as ns1)  
SELECT ProductID as 'ns1:ProductID',  
       Name      as 'ns1:Name',   
       Color     as 'ns1:Color'  
FROM Production.Product  
WHERE ProductID=316   
FOR XML RAW, ELEMENTS XSINIL  

Risultato:This is the result:

<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="uri">  
  <ns1:ProductID>316</ns1:ProductID>  
  <ns1:Name>Blade</ns1:Name>  
  <ns1:Color xsi:nil="true" />  
</row>  

Impostazione degli spazi dei nomi predefinitiSpecifying Default Namespaces

Anziché dichiarare un prefisso dello spazio dei nomi, è possibile dichiarare uno spazio dei nomi predefinito utilizzando la parola chiave DEFAULT.Instead of declaring a namespace prefix, you can declare a default namespace by using a DEFAULT keyword. Nella query FOR XML, questa parola chiave associa lo spazio dei nomi predefinito ai nodi XML nel codice XML risultante.In the FOR XML query, it will bind the default namespace to XML nodes in the resulting XML. Nell'esempio seguente, la clausola WITH XMLNAMESPACES definisce due prefissi di spazio dei nomi che vengono definiti insieme a uno spazio dei nomi predefinito.In the following example, the WITH XMLNAMESPACES defines two namespace prefixes that are defined together with a default namespace.

WITH XMLNAMESPACES ('uri1' as ns1,   
                    'uri2' as ns2,  
                    DEFAULT 'uri2')  
SELECT ProductID,   
      Name,  
      Color  
FROM Production.Product   
WHERE ProductID=316 or ProductID=317  
FOR XML RAW ('ns1:Product'), ROOT('ns2:root'), ELEMENTS  

La query FOR XML genera codice XML incentrato sugli elementi.The FOR XML query generates element-centric XML. Si noti che nella query entrambi i prefissi dello spazio dei nomi vengono utilizzati per la denominazione dei nodi.Note that the query uses both the namespace prefixes in naming nodes. Nella clausola SELECT, per l'ID prodotto, il nome e il colore non è specificato un nome con un prefissoIn the SELECT clause, the ProductID, Name, and Color do not specify a name with any prefix. e pertanto gli elementi corrispondenti nel codice XML risultante appartengono allo spazio dei nomi predefinito.Therefore, the corresponding elements in the resulting XML belong to the default namespace.

<ns2:root xmlns="uri2" xmlns:ns2="uri2" xmlns:ns1="uri1">  
  <ns1:Product>  
    <ProductID>316</ProductID>  
    <Name>Blade</Name>  
  </ns1:Product>  
  <ns1:Product>  
    <ProductID>317</ProductID>  
    <Name>LL Crankarm</Name>  
    <Color>Black</Color>  
  </ns1:Product>  
</ns2:root>  

La query seguente è simile alla precedente, eccetto che per il fatto che è specificata la modalità FOR XML AUTO.The following query is similar to the previous one, except that the FOR XML AUTO mode is specified.

WITH XMLNAMESPACES ('uri1' as ns1,  'uri2' as ns2,DEFAULT 'uri2')  
SELECT ProductID,   
      Name,  
      Color  
FROM Production.Product as "ns1:Product"  
WHERE ProductID=316 or ProductID=317  
FOR XML AUTO, ROOT('ns2:root'), ELEMENTS  

Utilizzo degli spazi dei nomi predefinitiUsing Predefined Namespaces

Quando si utilizzano gli spazi dei nomi predefiniti, è necessario specificare in modo esplicito l'associazione degli spazi dei nomi utilizzando WITH XMLNAMESPACES. Questa osservazione non è valida per lo spazio dei nomi xml e per lo spazio dei nomi xsi se si utilizza ELEMENTS XSINILWhen you use predefined namespaces, except the xml namespace and the xsi namespace when ELEMENTS XSINIL is used, you must explicitly specify the namespace binding by using WITH XMLNAMESPACES. La query seguente definisce in modo esplicito l'associazione tra il prefisso dello spazio dei nomi e l'URI per lo spazio dei nomi predefinito (urn:schemas-microsoft-com:xml-sql).The following query explicitly defines the namespace prefix to URI binding for the predefined namespace (urn:schemas-microsoft-com:xml-sql).

WITH XMLNAMESPACES ('urn:schemas-microsoft-com:xml-sql' as sql)  
SELECT 'SELECT * FROM Customers FOR XML AUTO, ROOT("a")' AS "sql:query"  
FOR XML PATH('sql:root')  

Di seguito è riportato il risultato.This is the result. Gli utenti di SQLXML hanno familiarità con questo modello XML.SQLXML users are familiar with this XML template. Per altre informazioni, vedere Concetti relativi alla programmazione SQLXML 4.0.For more information, see SQLXML 4.0 Programming Concepts.

<sql:root xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <sql:query>SELECT * FROM Customers FOR XML AUTO, ROOT("a")</sql:query>  
</sql:root>  

Il prefisso dello spazio dei nomi xml è l'unico che può essere utilizzato senza che sia necessario definirlo in modo esplicito in WITH XMLNAMESPACES, come illustrato nella query seguente in modalità PATH.Only the xml namespace prefix can be used without explicitly defining it in WITH XMLNAMESPACES, as shown in the following PATH mode query. Se si dichiara questo prefisso, è inoltre necessario associarlo allo spazio dei nomi http://www.w3.org/XML/1998/namespace.Also, if the prefix is declared, it has to be bound to the namespace http://www.w3.org/XML/1998/namespace. I nomi specificati nella clausola SELECT fanno riferimento al prefisso dello spazio dei nomi xml che non viene definito in modo esplicito tramite WITH XMLNAMESPACES.The names specified in the SELECT clause refer to the xml namespace prefix that is not explicitly defined by using WITH XMLNAMESPACES.

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

Gli attributi @xml:lang usano lo spazio dei nomi xml predefinito.The @xml:lang attributes use the predefined xml namespace. Poiché nella versione XML 1.0 non è necessario dichiarare in modo esplicito l'associazione dello spazio dei nomi xml, il risultato non includerà una dichiarazione esplicita di tale associazione.Because XML version 1.0 does not require the explicit declaration of the xml namespace binding, the result will not include an explicit declaration of the namespace binding.

Risultato:This is the result:

<Translation>  
  <English xml:lang="en">food</English>  
  <German xml:lang="ger">Essen</German>  
</Translation>  

Utilizzo di WITH XMLNAMESPACES con i metodi con tipo di dati xmlUsing WITH XMLNAMESPACES with the xml Data Type Methods

Tutti i metodi con tipo di dati xml specificati in una query SELECT o in UPDATE quando si tratta del metodo modify() , devono ripetere la dichiarazione dello spazio dei nomi nel prologo.The xml Data Type Methods specified in a SELECT query, or in UPDATE when it is the modify() method, all have to repeat the namespace declaration in their prolog. e possono richiedere pertanto molto tempo.This can be time-consuming. Ad esempio, la query seguente recupera gli ID dei modelli di prodotto per i quali esistono specifiche nelle descrizioni del catalogo,For example, the following query retrieves product model IDs whose catalog descriptions do include specification. ovvero per i quali esiste l'elemento <Specifications>.That is, the <Specifications> element exists.

SELECT ProductModelID, CatalogDescription.query('  
declare namespace pd="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
    <Product   
        ProductModelID= "{ sql:column("ProductModelID") }"   
        />  
') AS Result  
FROM Production.ProductModel  
WHERE CatalogDescription.exist('  
    declare namespace  pd="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
     /pd:ProductDescription[(pd:Specifications)]'  
    ) = 1  

Nella query precedente, entrambi i metodi query() e exist() dichiarano lo stesso spazio dei nomi nel rispettivo prologo.In the previous query, both the query() and exist() methods declare the same namespace in their prolog. Esempio:For example:

declare namespace pd="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  

In alternativa, è possibile dichiarare innanzitutto WITH XMLNAMESPACES e utilizzare i prefissi dello spazio dei nomi nella query.Alternatively, you can declare WITH XMLNAMESPACES first and use the namespace prefixes in the query. In questo caso, non è necessario che i metodi query() e exist() includano le dichiarazioni di spazio dei nomi nel prologo.In this case, the query() and exist() methods do not have to include namespace declarations in their prolog.

WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' as pd)  
SELECT ProductModelID, CatalogDescription.query('  
    <Product   
        ProductModelID= "{ sql:column("ProductModelID") }"   
        />  
') AS Result  
FROM Production.ProductModel  
WHERE CatalogDescription.exist('  
     /pd:ProductDescription[(pd:Specifications)]'  
    ) = 1  
Go  

Si noti che una dichiarazione esplicita nel prologo della query XQuery ignora il prefisso e lo spazio dei nomi predefinito definiti nella clausola WITH.Note that an explicit declaration in the XQuery prolog overrides the namespace prefix and the default element namespace that are defined in the WITH clause.

Vedere ancheSee Also

metodi con tipo di dati XML xml Data Type Methods
Riferimento al linguaggio XQuery (SQL Server) XQuery Language Reference (SQL Server)
WITH XMLNAMESPACES (Transact-SQL) WITH XMLNAMESPACES (Transact-SQL)
FOR XML (SQL Server) FOR XML (SQL Server)