Использование режима PATH
Как описано в разделе Создание XML с помощью предложения FOR XML, режим PATH является простым способом смешивания элементов и атрибутов. Режим PATH является также простым способом создания дополнительных вложенных объектов для отражения сложных свойств. Для построения таких XML-документов из набора строк можно использовать запросы FOR XML в режиме EXPLICIT, но режим PATH является более простой альтернативой зачастую громоздким запросам в режиме EXPLICIT. Режим PATH не просто позволяет писать вложенные запросы FOR XML с директивой TYPE для возврата экземпляров типа xml, он позволяет делать это гораздо проще.
В режиме PATH имена или псевдонимы столбцов обрабатываются как выражения XPath. Эти выражения показывают, как значения сопоставляются с XML-данными. Каждое выражение на языке XPath является относительным элементом XPath, предоставляющим такие сведения, как атрибут, элемент, скалярное значение, а также имя и иерархию узла, который будет сформирован в связи с элементом строки.
В этом подразделе описаны следующие варианты сопоставления столбцов в наборе строк:
- столбцы без имени;
- столбцы с именем;
- столбцы с именем в виде символа-шаблона (*);
- столбцы с именем XPath-функции проверки узла;
- имена столбцов с путем, указанным как data();
- столбцы, по умолчанию содержащие значение NULL.
Столбцы без имени
Любой столбец, не имеющий имени, будет встроенным. Например, вычисляемые столбцы или вложенные скалярные запросы, в которых не задан псевдоним столбца, формируют столбцы без имени. Если столбец имеет тип данных xml, в него помещается содержимое экземпляра этого типа данных. В противном случае содержимое столбца вставляется как текстовый узел.
SELECT 2+2
FOR XML PATH
Создание этого XML. По умолчанию для каждой строки в наборе строк в итоговом XML-документе формируется элемент <row
>. То же самое происходит в режиме RAW.
<row>4</row>
Следующий запрос возвращает набор строк с тремя столбцами. Третий столбец, без названия, содержит XML-данные. Режим PATH вставляет экземпляр типа xml.
SELECT ProductModelID,
Name,
Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
/MI:root/MI:Location
')
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH
go
Частичный результат:
<row>
<ProductModelID>7</ProductModelID>
<Name>HL Touring Frame</Name>
<MI:Location ...LocationID="10" ...></MI:Location>
<MI:Location ...LocationID="20" ...></MI:Location>
...
</row>
Столбцы с именем
Ниже приведены условия, при которых столбцы с именем из набора строк сопоставляются с учетом регистра с итоговым XML-документом:
- имя столбца начинается с символа @;
- имя столбца не начинается с символа @;
- имя столбца не начинается с символа @ и содержит косую черту (/);
- несколько столбцов имеют одинаковый префикс;
- один из столбцов имеет другое имя.
Имя столбца начинается с символа @
Если имя столбца начинается с символа @ и не содержит косую черту (/), создается атрибут элемента <row
>, имеющий соответствующее значение столбца. Например, следующий запрос возвращает набор строк с двумя столбцами (@PmId, Name). В итоговом XML-документе атрибут PmId добавляется к соответствующему элементу <row
> и ему присваивается значение столбца ProductModelID.
SELECT ProductModelID as "@PmId",
Name
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH
go
Результат:
<row PmId="7">
<Name>HL Touring Frame</Name>
</row>
Обратите внимание, что на одном уровне атрибуты должны располагаться перед любыми другими типами узлов, например перед узлами элементов и текстовыми узлами. Следующий запрос возвращает ошибку:
SELECT Name,
ProductModelID as "@PmId"
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH
go
Имя столбца не начинается с символа @
Если имя столбца начинается с символа @, не является одной из XPath-функций проверки узла и не содержит косую черту (/), по умолчанию создается элемент XML <row
>, который представляет собой вложенный элемент элемента строки.
В результате следующего запроса указывается имя столбца. Дочерний элемент <result
> добавляется к элементу <row
>.
SELECT 2+2 as result
for xml PATH
Результат:
<row>
<result>4</result>
</row>
Следующий запрос указывает имя столбца, ManuWorkCenterInformation, для XML-данных, возвращенных запросом XQuery, указанным по отношению к столбцу Instructions типа xml. Элемент <ManuWorkCenterInformation
> добавляется в качестве дочернего к элементу <row
>.
SELECT
ProductModelID,
Name,
Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
/MI:root/MI:Location
') as ManuWorkCenterInformation
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH
go
Результат:
<row>
<ProductModelID>7</ProductModelID>
<Name>HL Touring Frame</Name>
<ManuWorkCenterInformation>
<MI:Location ...LocationID="10" ...></MI:Location>
<MI:Location ...LocationID="20" ...></MI:Location>
...
</ManuWorkCenterInformation>
</row>
Имя столбца не начинается с символа @ и содержит косую черту (/)
Если имя столбца не начинается с символа @, но содержит косую черту (/), оно является признаком иерархии XML. Например, если столбец имеет имя «Имя1/Имя2/Имя3.../Имяn», каждое Имяi представляет имя элемента, вложенного в элемент текущей строки (для i=1) или расположенного под элементом Имяi-1. Если Имяn начинается с символа @, оно сопоставляется с атрибутом элемента Имяn-1.
Например, следующий запрос возвращает идентификатор работника и имя, представленное сложным элементом EmpName, который включает в себя имя, отчество и фамилию работника.
SELECT EmployeeID "@EmpID",
FirstName "EmpName/First",
MiddleName "EmpName/Middle",
LastName "EmpName/Last"
FROM HumanResources.Employee E, Person.Contact C
WHERE E.EmployeeID = C.ContactID
AND E.EmployeeID=1
FOR XML PATH
Имена столбцов используются в качестве пути при построении XML-документа в режиме PATH. Имя столбца, содержащего значения идентификатора работника, начинается с символа @. Поэтому атрибут EmpID добавляется к элементу <row
>. Имена всех других столбцов содержат символ косой черты (/), являющийся признаком иерархии. В итоговом XML-документе будет присутствовать дочерний элемент <EmpName
> внутри элемента <row
>, а элемент <EmpName
> будет в свою очередь содержать дочерние элементы <First
>, <Middle
> и <Last
>.
<row EmpID="1">
<EmpName>
<First>Gustavo</First>
<Last>Achong</Last>
</EmpName>
</row>
Отчество работника имеет значение NULL, которое по умолчанию сопоставляется с отсутствием элемента или атрибута. Если необходимо сформировать элементы для значений NULL, укажите директиву ELEMENTS с ключевым словом XSINIL, как показано в данном запросе.
SELECT EmployeeID "@EmpID",
FirstName "EmpName/First",
MiddleName "EmpName/Middle",
LastName "EmpName/Last"
FROM HumanResources.Employee E, Person.Contact C
WHERE E.EmployeeID = C.ContactID
AND E.EmployeeID=1
FOR XML PATH, ELEMENTS XSINIL
Результат:
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
EmpID="1">
<EmpName>
<First>Gustavo</First>
<Middle xsi:nil="true" />
<Last>Achong</Last>
</EmpName>
</row>
По умолчанию в режиме PATH формируется элементно-ориентированный XML-документ. Поэтому указание директивы ELEMENTS в режиме PATH не имеет никакого смысла. Однако, как показано в предыдущем примере, директива ELEMENTS с ключевым словом XSINIL может быть полезна при формировании элементов для значений NULL.
Следующий запрос кроме идентификатора и имени возвращает еще и адрес работника. В соответствии с путем, указанным в именах столбцов адресов, дочерний элемент <Address
> добавляется к элементу <row
>, а подробные сведения об адресе добавляются в качестве дочерних элементов к элементу <Address
>.
SELECT EmployeeID "@EmpID",
FirstName "EmpName/First",
MiddleName "EmpName/Middle",
LastName "EmpName/Last",
AddressLine1 "Address/AddrLine1",
AddressLine2 "Address/AddrLIne2",
City "Address/City"
FROM HumanResources.Employee E, Person.Contact C, Person.Address A
WHERE E.EmployeeID = C.ContactID
AND E.AddressID = A.AddressID
AND E.EmployeeID=1
FOR XML PATH
Результат:
<row EmpID="1">
<EmpName>
<First>Gustavo</First>
<Last>Achong</Last>
</EmpName>
<Address>
<AddrLine1>7726 Driftwood Drive</AddrLine1>
<City>Monroe</City>
</Address>
</row>
Несколько столбцов имеют одинаковый префикс пути
Если несколько последовательных столбцов имеют одинаковый префикс пути, производится их группировка под одним именем. Если используется одно и то же пространство имен, но разные префиксы пространства имен, путь считается отличающимся. В предыдущем запросе столбцы FirstName, MiddleName и LastName имеют один и тот же префикс EmpName. Поэтому они добавляются как дочерние элементы элемента <EmpName
>. Это справедливо также для случая создания элемента <Address
>, показанного в предыдущем примере.
Один из столбцов имеет другое имя
Если между столбцами встречается столбец с другим именем, группирование будет нарушено, как это показано в следующем измененном запросе. Добавляя столбцы с адресом между столбцами FirstName и MiddleName, данный запрос нарушает группирование столбцов FirstName, MiddleName и LastName, указанное в предыдущем запросе.
SELECT EmployeeID "@EmpID",
FirstName "EmpName/First",
AddressLine1 "Address/AddrLine1",
AddressLine2 "Address/AddrLIne2",
City "Address/City",
MiddleName "EmpName/Middle",
LastName "EmpName/Last"
FROM HumanResources.EmployeeAddress E, Person.Contact C, Person.Address A
WHERE E.EmployeeID = C.ContactID
AND E.AddressID = A.AddressID
AND E.EmployeeID=1
FOR XML PATH
В результате запрос создает два элемента <EmpName
>. Первый элемент <EmpName
> имеет дочерний элемент <FirstName
>, а второй элемент <EmpName
> имеет дочерние элементы <MiddleName
> и <LastName
>.
Результат:
<row EmpID="1">
<EmpName>
<First>Gustavo</First>
</EmpName>
<Address>
<AddrLine1>7726 Driftwood Drive</AddrLine1>
<City>Monroe</City>
</Address>
<EmpName>
<Last>Achong</Last>
</EmpName>
</row>
Столбцы с именем в виде символа-шаблона (*)
Если имя столбца содержит символ-шаблон (*), содержимое этого столбца вставляется, как будто имя не указано совсем. Если этот столбец не является столбцом типа xml, содержимое столбца вставляется в качестве текстового узла так, как это показано в следующем примере:
SELECT EmployeeID "@EmpID",
FirstName "*",
MiddleName "*",
LastName "*"
FROM HumanResources.Employee E, Person.Contact C
WHERE E.EmployeeID = C.ContactID
AND E.EmployeeID=1
FOR XML PATH
Результат:
<row EmpID="1">GustavoAchong</row>
Если столбец имеет тип xml, вставляется соответствующее дерево XML. Например, в следующем запросе столбец, содержащий XML-данные, возвращенные в результате запроса на языке XQuery к столбцу Instructions, имеет имя «*».
SELECT
ProductModelID,
Name,
Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"
/MI:root/MI:Location
') as "*"
FROM Production.ProductModel
WHERE ProductModelID=7
FOR XML PATH
go
Результат. Запрос на языке XQuery возвращает XML-данные, которые вставляются без закрытия элемента.
<row>
<ProductModelID>7</ProductModelID>
<Name>HL Touring Frame</Name>
<MI:Location LocationID="10">...</MI:Location>
<MI:Location LocationID="20">...</MI:Location>
...
</row>
Столбцы с именем XPath-функции проверки узла
Если имя столбца является одной из XPath-функций проверки узла, сопоставление содержимого производится, как указано в следующей таблице.
Когда имя столбца является XPath-функцией проверки узла, содержимое сопоставляется с соответствующим узлом. Если столбец имеет SQL-тип xml, возвращается ошибка.
Имя столбца | Поведение |
---|---|
text() |
Строковое значение столбца с именем text() добавляется в качестве текстового узла. |
comment() |
Строковое значение столбца с именем text() добавляется в качестве комментария XML. |
node() |
Для столбца с именем node() результат аналогичен результату, получаемому для столбца с символом-шаблоном (*) в качестве имени. |
processing-instruction(name) |
Строковое значение столбца с именем инструкции обработки добавляется в качестве значения инструкции для целевого имени инструкции обработки. |
Имена столбцов с путем, указанным как data()
Если путь для имени столбца указан как «data()», то в сформированном XML-документе его значение обрабатывается как элементарное. Если следующий элемент последовательности также является элементарным значением, в XML-документ добавляется символ пробела. Это может пригодиться при создании списка типизированных элементов и значений атрибутов. Следующий запрос извлекает код модели продукции, ее имя и список продуктов этой модели.
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"
FROM Production.ProductModel
WHERE ProductModelID= 7
FOR XML PATH('ProductModelData')
Вложенная инструкция SELECT извлекает список кодов продуктов. Имя столбца для кодов продуктов в нем указано как «data()». Поскольку режим PATH указывает для имени элемента строки пустую строку, формирования элемента строки не происходит. Вместо этого возвращаются значения, назначенные атрибуту ProductIDs элемента строки <ProductModelData
> в родительской инструкции SELECT. Результат:
<ProductModelData ProductModelID="7"
ProductModelName="HL Touring Frame"
ProductIDs="885 887 888 889 890 891 892 893" />
Столбцы, по умолчанию содержащие значение NULL
По умолчанию значение NULL в столбце сопоставляется с отсутствием атрибута, узла или элемента. Это поведение, установленное по умолчанию, может быть изменено с помощью запроса к элементно-ориентированному документу XML с использованием директивы ELEMENTS и указания ключевого слова XSINIL для добавления элементов для значений NULL, как показано в следующем запросе:
SELECT EmployeeID as "@EmpID",
FirstName as "EmpName/First",
MiddleName as "EmpName/Middle",
LastName as "EmpName/Last"
FROM HumanResources.Employee E, Person.Contact C
WHERE E.EmployeeID = C.ContactID
AND E.EmployeeID=1
FOR XML PATH, ELEMENTS XSINIL
Ниже показан результат. Обратите внимание, что, если ключевое слово XSINIL не указано, элемент <Middle
> будет отсутствовать.
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" EmpID="1">
<EmpName>
<First>Gustavo</First>
<Middle xsi:nil="true" />
<Last>Achong</Last>
</EmpName>
</row>
Поддержка пространства имен
В этом выпуске поддержка пространства имен в режиме PATH осуществляется с помощью предложения WITH NAMESPACES. Например, в следующем запросе синтаксис WITH NAMESPACES применяется для объявления пространства имен («a:»), которое затем можно использовать в последующей инструкции SELECT:
WITH XMLNAMESPACES('a' as a)
SELECT 1 as 'a:b'
FOR XML PATH
Примеры
В этих примерах показано использование режима PATH при формировании XML-документа из запроса SELECT. Многие из этих запросов являются запросами к XML-документам с инструкциями по производству велосипедов, хранящимся в столбце Instructions таблицы ProductModel. Дополнительные сведения об инструкциях XML см. в разделе Представление типов xml-данных в базе данных AdventureWorks.
A. Указание простого запроса в режиме PATH
Этот запрос указывает режим FOR XML PATH.
SELECT
ProductModelID,
Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH
go
Следующий результат представляет собой элементно-ориентированный XML, в котором значение каждого столбца в итоговом наборе строк образует элемент. Поскольку предложение SELECT не указывает псевдонимы для имен столбцов, формируются имена дочерних элементов, совпадающие с именами соответствующих столбцов в предложении SELECT. Для каждой строки в наборе строк добавляется тег <row
>.
<row>
<ProductModelID>122</ProductModelID>
<Name>All-Purpose Bike Stand</Name>
</row>
<row>
<ProductModelID>119</ProductModelID>
<Name>Bike Wash</Name>
</row>
Следующий результат совпадает с результатом запроса в режиме RAW с указанным параметром ELEMENTS. Запрос возвращает элементно-ориентированный XML с установленным по умолчанию элементом <row
> для каждой строки в наборе результатов.
SELECT ProductModelID,
Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML RAW, ELEMENTS
Дополнительно можно указать имя элемента строки, которое переопределит значение по умолчанию <row
>. Например, следующий запрос возвращает элемент <ProductModel
> для каждой строки в наборе строк.
SELECT ProductModelID,
Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModel')
Go
Итоговый XML-документ будет иметь указанное имя элемента строки.
<ProductModel>
<ProductModelID>122</ProductModelID>
<Name>All-Purpose Bike Stand</Name>
</ProductModel>
<ProductModel>
<ProductModelID>119</ProductModelID>
<Name>Bike Wash</Name>
</ProductModel>
Если указать строку нулевой длины, элемент не закрывается.
SELECT ProductModelID,
Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('')
Go
Результат:
<ProductModelID>122</ProductModelID>
<Name>All-Purpose Bike Stand</Name>
<ProductModelID>119</ProductModelID>
<Name>Bike Wash</Name>
Б. Указание имен столбцов, подобных синтаксису языка XPath
В следующем запросе указанное имя столбца ProductModelID начинается с символа @ и не содержит косой черты (/). Поэтому в итоговом XML-документе создается атрибут элемента <row
>, имеющий соответствующее значение столбца.
SELECT ProductModelID as "@id",
Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModelData')
go
Результат:
< ProductModelData id="122">
<Name>All-Purpose Bike Stand</Name>
</ ProductModelData >
< ProductModelData id="119">
<Name>Bike Wash</Name>
</ ProductModelData >
С помощью указания в запросе FOR XML параметра root можно добавить один элемент верхнего уровня.
SELECT ProductModelID as "@id",
Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML PATH ('ProductModelData'), root ('Root')
go
Для формирования иерархии можно добавить синтаксис, подобный PATH. Если, например, изменить имя столбца Name на «SomeChild/ModelName», можно получить XML-документ с иерархией, показанной в следующем результате:
<Root>
<ProductModelData id="122">
<SomeChild>
<ModelName>All-Purpose Bike Stand</ModelName>
</SomeChild>
</ProductModelData>
<ProductModelData id="119">
<SomeChild>
<ModelName>Bike Wash</ModelName>
</SomeChild>
</ProductModelData>
</Root>
Следующий запрос извлекает не только код модели продукта и его имя, но и расположения производственных инструкций для модели продукции. Поскольку столбец Instructions имеет тип xml, то для получения расположения указывается метод query() типа данных xml.
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
Частичный результат. Поскольку в данном запросе имя столбца указано как ManuInstr, XML-данные, возвращенные методом query(), помещаются в тег <ManuInstr
>, как показано ниже:
<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>
В предыдущий запрос FOR XML можно было включить пространства имен для элементов <Root
> и <ProductModelData
>. Для этого следовало сначала определить префикс пространства имен, создать привязку с помощью предложения WITH XMLNAMESPACES и затем использовать префиксы в запросе FOR XML. Дополнительные сведения см. в разделе Добавление пространств имен с помощью предложения WITH XMLNAMESPACES.
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
Обратите внимание, что префикс MI также определяется в предложении WITH XMLNAMESPACES. В результате метод query() типа xml не определяет префикс в прологе запроса. Результат:
<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" >
<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>
В. Формирование списка значений с помощью режима PATH
Данный запрос строит список значений кодов продуктов для каждой модели продукции. Кроме того, для каждого кода продукта запрос создает вложенные элементы <ProductName
>, как показано в следующем фрагменте XML:
<ProductModelData ProductModelID="7" ProductModelName="..."
ProductIDs="product id list in the product model" >
<ProductName>...</ProductName>
<ProductName>...</ProductName>
...
</ProductModelData>
Это запрос, создающий желаемый XML:
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 ('')) as "ProductNames"
FROM Production.ProductModel
WHERE ProductModelID= 7 or ProductModelID=9
FOR XML PATH('ProductModelData')
Обратите внимание на следующее в предыдущем запросе:
- Первая вложенная инструкция SELECT возвращает список столбцов ProductID, для чего использует значение data() в качестве имени столбца. Поскольку в режиме FOR XML PATH запрос указывает для имени элемента строки пустую строку, формирование элемента не происходит. Вместо этого атрибуту ProductID назначается список значений.
- Вторая вложенная инструкция SELECT извлекает имена продуктов для модели продукта. Запрос формирует элементы <
ProductName
>, которые возвращаются в виде элементов <ProductNames
>, поскольку в качестве имени столбца в запросе указано ProductNames.
Частичный результат:
<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>
Вложенный запрос, формирующий имена продуктов, возвращает результат в виде строки, которая преобразуется в сущность и затем добавляется в XML-документ. Если добавить директиву типа FOR XML PATH (''), type
, вложенный запрос возвращает результат как тип xml, а преобразования в сущность не происходит.
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')
Г. Добавление пространств имен в итоговый XML-документ
Как описано в разделе Добавление пространств имен с помощью предложения WITH XMLNAMESPACES, предложение WITH XMLNAMESPACES может использоваться для включения пространств имен в запросы в режиме PATH. Например, имена, указанные в предложении SELECT, имеют префиксы пространства имен. Следующий запрос режима PATH строит XML-документ с пространствами имен.
SELECT 'en' as "English/@xml:lang",
'food' as "English",
'ger' as "German/@xml:lang",
'Essen' as "German"
FOR XML PATH ('Translation')
go
Атрибут @xml:lang
, добавляемый к элементу <English
>, определяется в предварительно заданном пространстве имен xml.
Результат:
<Translation>
<English xml:lang="en">food</English>
<German xml:lang="ger">Essen</German>
</Translation>
Следующий запрос похож на приведенный в примере В, отличаясь тем, что в нем пространства имен добавляются в результирующий XML-документ с помощью предложения WITH XMLNAMESPACES. Дополнительные сведения см. в разделе Добавление пространств имен с помощью предложения WITH XMLNAMESPACES.
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')
Результат:
<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>
См. также
Справочник
Создание XML с помощью предложения FOR XML
Основные понятия
Добавление пространств имен с помощью предложения WITH XMLNAMESPACES