Agregar espacios de nombres a consultas con WITH XMLNAMESPACESAdd Namespaces to Queries with WITH XMLNAMESPACES

SE APLICA A: síSQL Server noAzure SQL Database noAzure Synapse Analytics (SQL DW) noAlmacenamiento de datos paralelos APPLIES TO: yesSQL Server noAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

WITH XMLNAMESPACES (Transact-SQL) proporciona compatibilidad con los URI de espacio de nombres de la siguiente manera:WITH XMLNAMESPACES (Transact-SQL) provides namespace URI support in the following way:

Utilizar WITH XMLNAMESPACES en las consultas FOR XMLUsing WITH XMLNAMESPACES in the FOR XML Queries

WITH XMLNAMESPACES permite incluir espacios de nombres XML en las consultas FOR XML.WITH XMLNAMESPACES lets you include XML namespaces in FOR XML queries. Por ejemplo, considere la siguiente consulta FOR XML:For example, consider the following FOR XML query:

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

El resultado es el siguiente:This is the result:

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

Para agregar espacios de nombres al XML generado por la consulta FOR XML, especifique primero las asignaciones de los prefijos de espacio de nombres a los URI mediante la cláusula 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. A continuación, utilice los prefijos de espacio de nombres para especificar los nombres en la consulta, como se muestra en la siguiente consulta modificada.Then, use the namespace prefixes in specifying the names in the query as shown in the following modified query. Tenga en cuenta que la cláusula WITH XMLNAMESPACES especifica la asignación del prefijo de espacio de nombres (ns1) al URI (uri).Note that the WITH XMLNAMESPACES clause specifies the namespace prefix (ns1) to URI (uri) mapping. Después, el prefijo ns1 se usa para especificar los nombres de elementos y atributos que la cláusula FOR XML debe generar.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  
  

El resultado XML incluye los prefijos de espacio de nombres: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>  
  

La siguiente información se aplica a la cláusula WITH XMLNAMESPACES:The following applies to the WITH XMLNAMESPACES clause:

  • Se admite solamente en los modos RAW, AUTO y PATH de las consultas FOR XML.It is supported only on the RAW, AUTO, and PATH modes of the FOR XML queries. No se admite el modo EXPLICIT.The EXPLICIT mode is not supported.

  • Afecta a los prefijos de espacio de nombres de las consultas FOR XML y a los métodos del tipo de datos xml , pero no al analizador XML.It only affects the namespace prefixes of FOR XML queries and the xml data type methods, but not the XML parser. Por ejemplo, la consulta siguiente devuelve un error porque el documento XML no tiene ninguna declaración de espacio de nombres para el prefijo myNS.For example, the following query returns an error, because the XML document has no namespace declaration for the myNS prefix.

  • Las directivas FOR XML, XMLSCHEMA y XMLDATA no se pueden utilizar con una cláusula WITH XMLNAMESPACES.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 ('https://abc' as myNS )  
    INSERT INTO T VALUES('<myNS:root/>')  
    

Utilizar la directiva XSINILUsing the XSINIL Directive

No se puede definir el prefijo xsi en la cláusula WITH XMLNAMESPACES si se utiliza la directiva ELEMENTS XSINIL.You cannot define the xsi prefix in the WITH XMLNAMESPACES clause if you are using the ELEMENTS XSINIL directive. En su lugar, se agrega automáticamente cuando se utiliza ELEMENTS XSINIL.Instead, it is added automatically when you use ELEMENTS XSINIL. La consulta siguiente usa ELEMENTS XSINIL, que genera XML centrado en elementos donde los valores NULL se asignan a elementos que tienen el atributo xsi:nil establecido en 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  

El resultado es el siguiente: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>  

Especificar espacios de nombres predeterminadosSpecifying Default Namespaces

En lugar de declarar un prefijo de espacio de nombres, se puede declarar un espacio de nombres predeterminado mediante la palabra clave DEFAULT.Instead of declaring a namespace prefix, you can declare a default namespace by using a DEFAULT keyword. En la consulta FOR XML, enlazará el espacio de nombres predeterminado con los nodos XML del XML resultante.In the FOR XML query, it will bind the default namespace to XML nodes in the resulting XML. En el ejemplo siguiente, WITH XMLNAMESPACES especifica dos prefijos de espacio de nombres definidos con un espacio de nombres predeterminado.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 consulta FOR XML genera XML centrado en elementos.The FOR XML query generates element-centric XML. Observe que la consulta utiliza los prefijos de espacio de nombres para asignar nombres a los nodos.Note that the query uses both the namespace prefixes in naming nodes. En la cláusula SELECT, ProductID, Name y Color no especifican un nombre con ningún prefijo.In the SELECT clause, the ProductID, Name, and Color do not specify a name with any prefix. Por lo tanto, los elementos correspondientes en el XML resultante pertenecen al espacio de nombres predeterminado.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 consulta siguiente es similar a la anterior, con la diferencia de que se especifica el modo AUTO de FOR XML.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  

Utilizar espacios de nombres predefinidosUsing Predefined Namespaces

Si se utilizan espacios de nombres predefinidos, excepto los espacios de nombres xml y xsi cuando se utiliza ELEMENTS XSINIL, es necesario especificar explícitamente el enlace con el espacio de nombres por medio de WITH XMLNAMESPACES.When 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. En la consulta siguiente se define explícitamente el enlace entre el prefijo de espacio de nombres y el URI para el espacio de nombres predefinido (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')  

Éste es el resultado.This is the result. Los usuarios de SQLXML están familiarizados con esta plantilla XML.SQLXML users are familiar with this XML template. Para obtener más información, vea Conceptos de programación en 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>  

Solo se puede utilizar el prefijo de espacio de nombres xml sin definirlo explícitamente en WITH XMLNAMESPACES, como se muestra en la siguiente consulta en modo PATH.Only the xml namespace prefix can be used without explicitly defining it in WITH XMLNAMESPACES, as shown in the following PATH mode query. Por otra parte, si se declara el prefijo, debe estar enlazado con el espacio de nombres 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. Los nombres especificados en la cláusula SELECT hacen referencia al prefijo de espacio de nombres xml que no se define explícitamente mediante 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  

Los atributos @xml:lang usan el espacio de nombres xml predefinido.The @xml:lang attributes use the predefined xml namespace. Debido a que la versión 1.0 de XML no requiere la declaración explícita del enlace del espacio de nombres xml, el resultado no incluirá una declaración explícita del enlace de espacio de nombres.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.

El resultado es el siguiente:This is the result:

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

Utilizar WITH XMLNAMESPACES con los métodos del tipo de datos xmlUsing WITH XMLNAMESPACES with the xml Data Type Methods

Los métodos del tipo de datos xml especificados en una consulta SELECT, o en UPDATE en el caso del método modify() , deben repetir la declaración del espacio de nombres en el prólogo.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. Esto puede resultar lento.This can be time-consuming. Por ejemplo, la consulta siguiente recupera los identificadores de modelo de producto cuyas descripciones de catálogo no incluyen la especificación.For example, the following query retrieves product model IDs whose catalog descriptions do include specification. Es decir, el elemento <Specifications> existe.That is, the <Specifications> element exists.

SELECT ProductModelID, CatalogDescription.query('  
declare namespace pd="https://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="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
     /pd:ProductDescription[(pd:Specifications)]'  
    ) = 1  

En la consulta anterior, los métodos query() y exist() declaran el mismo espacio de nombres en el prólogo.In the previous query, both the query() and exist() methods declare the same namespace in their prolog. Por ejemplo:For example:

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

Alternativamente, se puede declarar primero WITH XMLNAMESPACES y utilizar los prefijos de espacio de nombres en la consulta.Alternatively, you can declare WITH XMLNAMESPACES first and use the namespace prefixes in the query. En este caso, los métodos query() y exist() no tienen que incluir las declaraciones de espacio de nombres en el prólogo.In this case, the query() and exist() methods do not have to include namespace declarations in their prolog.

WITH XMLNAMESPACES ('https://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  

Debe tenerse en cuenta que una declaración explícita en el prólogo de una consulta XQuery reemplazará el prefijo de espacio de nombres y el espacio de nombres predeterminado del elemento definidos en la cláusula 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.

Consulte tambiénSee Also

métodos del tipo de datos xml xml Data Type Methods
Referencia del lenguaje XQuery (SQL Server) XQuery Language Reference (SQL Server)
WITH XMLNAMESPACES (Transact-SQL) WITH XMLNAMESPACES (Transact-SQL)
FOR XML (SQL Server)FOR XML (SQL Server)