Добавление пространств имен в запросы с WITH XMLNAMESPACESAdd Namespaces to Queries with WITH XMLNAMESPACES

ОБЛАСТЬ ПРИМЕНЕНИЯ: даSQL Server нетБаза данных SQL Azure нетAzure Synapse Analytics (хранилище данных SQL) нетParallel Data Warehouse APPLIES TO: yesSQL Server noAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

ПредложениеWITH XMLNAMESPACES (Transact-SQL) поддерживает пространство имен URI следующим образом:WITH XMLNAMESPACES (Transact-SQL) provides namespace URI support in the following way:

Использование предложения WITH XMLNAMESPACES в запросах FOR XMLUsing WITH XMLNAMESPACES in the FOR XML Queries

Использование предложения WITH XMLNAMESPACES позволяет включать пространства имен XML в запросы FOR XML.WITH XMLNAMESPACES lets you include XML namespaces in FOR XML queries. Например, рассмотрим следующий запрос 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  

Результат:This is the result:

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

Чтобы добавить пространства имен в XML-документ, созданный с помощью запроса FOR XML, вначале с помощью предложения WITH NAMESPACES укажите префикс пространства имен для сопоставления с адресом URI.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. Затем используйте эти префиксы пространств имен для указания имен в запросе, как показано в следующем измененном запросе.Then, use the namespace prefixes in specifying the names in the query as shown in the following modified query. Обратите внимание, что предложение WITH XMLNAMESPACES указывает префикс пространства имен (ns1) для сопоставления с адресом URI (uri).Note that the WITH XMLNAMESPACES clause specifies the namespace prefix (ns1) to URI (uri) mapping. Затем префикс ns1 используется для указания создаваемого элемента и имен атрибутов в запросе 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  
  

Результирующий XML-документ содержит префиксы пространства имен: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>  
  

Предложение WITH XMLNAMESPACES имеет следующее применение:The following applies to the WITH XMLNAMESPACES clause:

  • Оно может быть использовано в запросах FOR XML только в режимах RAW, AUTO и PATH.It is supported only on the RAW, AUTO, and PATH modes of the FOR XML queries. Режим EXPLICIT не поддерживается.The EXPLICIT mode is not supported.

  • Оно влияет только на префиксы пространств имен в запросах FOR XML и методах типа данных xml , но не на синтаксический анализатор XML.It only affects the namespace prefixes of FOR XML queries and the xml data type methods, but not the XML parser. Например, в результате выполнения следующего запроса будет получена ошибка, так как в XML-документе не содержится пространства имени, связанного с префиксом myNS.For example, the following query returns an error, because the XML document has no namespace declaration for the myNS prefix.

  • Такие директивы FOR XML, как XMLSCHEMA и XMLDATA, не могут быть использованы в предложении 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/>')  
    

Использование директивы XSINILUsing the XSINIL Directive

При использовании директивы ELEMENTS XSINIL xsi-префиксы в предложении WITH XMLNAMESPACES использовать нельзя.You cannot define the xsi prefix in the WITH XMLNAMESPACES clause if you are using the ELEMENTS XSINIL directive. При использовании директивы ELEMENTS XSINIL префиксы добавляются автоматически.Instead, it is added automatically when you use ELEMENTS XSINIL. В следующем запросе используется директива ELEMENTS XSINIL, формирующая ориентированный на элементы XML-документ, в котором пустые значения сопоставляются с элементами, для которых атрибут xsi:nil имеет значение 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  

Результат: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>  

Указание пространств имен по умолчаниюSpecifying Default Namespaces

Вместо объявления префикса пространства имени можно объявить пространство имени с помощью ключевого слова DEFAULT.Instead of declaring a namespace prefix, you can declare a default namespace by using a DEFAULT keyword. В запросе FOR XML таким образом происходит привязка пространства имен по умолчанию к XML-узлам результирующего XML-документа.In the FOR XML query, it will bind the default namespace to XML nodes in the resulting XML. В представленном ниже примере с помощью предложения WITH XMLNAMESPACES задается два префикса пространства имен, которые определяются вместе с пространством имен по умолчанию.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  

В результате выполнения запроса FOR XML формируется ориентированный на элементы XML-документ.The FOR XML query generates element-centric XML. Заметим, что в запросе используются оба префикса пространства имен в узле имен.Note that the query uses both the namespace prefixes in naming nodes. В предложении SELECT параметры ProductID, Name и Color не указывают имен с какими-либо префиксами.In the SELECT clause, the ProductID, Name, and Color do not specify a name with any prefix. Поэтому соответствующие элементы в результирующем XML-документе принадлежат к пространству имен по умолчанию.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>  

Приведенный ниже запрос повторяет предыдущий за исключением указания режима 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  

Использование предопределенных пространств именUsing Predefined Namespaces

При использовании предопределенных пространств имен, кроме случаев использования пространств имен xml и xsi в директиве ELEMENTS XSINIL, необходимо явно указывать привязку пространств имен в предложении 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. В следующем запросе происходит задание префикса пространства имен для привязки к адресу URI для предопределенного пространства имен (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')  

Результат.This is the result. Данный XML-шаблон известен пользователям SQLXML.SQLXML users are familiar with this XML template. Дополнительные сведения см. в статье Основные понятия о программировании для 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>  

Только XML-префикс пространства имен может быть использован без явного задания в предложении WITH XMLNAMESPACES, как показано в следующем примере запроса в режиме PATH.Only the xml namespace prefix can be used without explicitly defining it in WITH XMLNAMESPACES, as shown in the following PATH mode query. Также при объявлении префикса его необходимо привязать к пространству имен 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. Имена, указанные в предложении SELECT, ссылаются на XML-префикс пространства имен, который не был явно задан с помощью предложения 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  

Атрибуты @xml:lang используют предопределенное пространство имен XML.The @xml:lang attributes use the predefined xml namespace. Так как в XML версии 1.0 нет необходимости явно задавать привязку пространства имен XML, то она не включается в результат.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.

Результат:This is the result:

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

Использование предложения WITH XMLNAMESPACES с методами типа данных xmlUsing WITH XMLNAMESPACES with the xml Data Type Methods

Все методы типа данных xml , указанные в запросе SELECT (или UPDATE в случае метода modify() ), должны повторять в своем прологе объявление пространства имен.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. Это может занять некоторое время.This can be time-consuming. Например, в результате выполнения следующего запроса получаются идентификаторы моделей, в описание каталогов которых включены спецификации.For example, the following query retrieves product model IDs whose catalog descriptions do include specification. То есть те, для которых существует элемент <Specifications>.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  

В представленном выше запросе в прологах обоих методов ( query() и exist() ) объявляются одинаковые пространства имен.In the previous query, both the query() and exist() methods declare the same namespace in their prolog. Пример:For example:

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

Того же результата можно достичь, если вначале объявить предложение WITH XMLNAMESPACES, а затем использовать указанные в нем префиксы пространства имен в запросе.Alternatively, you can declare WITH XMLNAMESPACES first and use the namespace prefixes in the query. В таком случае в прологах обоих методов ( query() и exist() ) пространства имен не объявляются.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  

Обратите внимание, что при явном объявлении в прологе запроса на языке XQuery, указанные в нем префиксы пространства имен переопределяют все указанные ранее и заданные по умолчанию с помощью предложения 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.

См. также:See Also

методов типа данных xml xml Data Type Methods
Справочник по языку XQuery (SQL Server) XQuery Language Reference (SQL Server)
WITH XMLNAMESPACES (Transact-SQL) WITH XMLNAMESPACES (Transact-SQL)
FOR XML (SQL Server)FOR XML (SQL Server)