Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 For Xml Path и default namespace  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1838
Имея запрос:
+
;WITH XMLNAMESPACES (DEFAULT 'http://www.w3schools.com')
SELECT
  1 AS col1,
  rez.bbb
FROM
  (SELECT NULL AS col) AS tbl
  CROSS APPLY (SELECT
                 2 AS col2
               FOR XML PATH(''), TYPE
              ) AS rez(bbb)
FOR XML PATH('xml'), TYPE

получаем
<xml xmlns="http://www.w3schools.com">
  <col1>1</col1>
  <bbb>
    <col2 xmlns="http://www.w3schools.com">2</col2>
  </bbb>
</xml>

Если изменим так:
+

;WITH XMLNAMESPACES (DEFAULT 'http://www.w3schools.com')
SELECT
  1 AS col1,
  rez.bbb.query('.')
FROM
  (SELECT NULL AS col) AS tbl
  CROSS APPLY (SELECT
                 2 AS col2
               FOR XML PATH('bbb'), TYPE
              ) AS rez(bbb)
FOR XML PATH('xml'), TYPE

получим
<xml xmlns="http://www.w3schools.com">
  <col1>1</col1>
  <bbb xmlns="http://www.w3schools.com">
    <col2>2</col2>
  </bbb>
</xml>


А надо получить:
<xml xmlns="http://www.w3schools.com">
  <col1>1</col1>
  <bbb>
    <col2>2</col2>
  </bbb>
</xml>

Есть один ущербный вариант:
+
SELECT
  CAST(
  N'<xml xmlns="http://www.w3schools.com">' +
  CAST(rez.r.query('/xml/*') AS NVARCHAR(MAX)) +
  N'</xml>' AS XML)
FROM
(
  SELECT
    1 AS col1,
    rez.bbb
  FROM
    (SELECT NULL AS col) AS tbl
    CROSS APPLY (SELECT
                   2 AS col2
                 FOR XML PATH(''), TYPE
                ) AS rez(bbb)
  FOR XML PATH('xml'), TYPE
) AS rez(r)

Вопрос. Есть ли способ решения проблемы не используя режим EXPLICIT и без CAST ?
P.S. Xml очень большой и многоуровневый, xmlns проставляется почти везде.
29 ноя 16, 19:39    [19948869]     Ответить | Цитировать Сообщить модератору
 Re: For Xml Path и default namespace  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
https://connect.microsoft.com/SQLServer/feedback/details/265956/suppress-namespace-attributes-in-nested-select-for-xml-statements
29 ноя 16, 19:48    [19948896]     Ответить | Цитировать Сообщить модератору
 Re: For Xml Path и default namespace  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
WITH XMLNAMESPACES(DEFAULT 'http://www.w3schools.com')
SELECT 1 as col1,
	   2 AS [bbb/col2]
FOR XML PATH('xml')


29 ноя 16, 19:53    [19948913]     Ответить | Цитировать Сообщить модератору
 Re: For Xml Path и default namespace  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
Вариант с XQuery:

WITH XMLNAMESPACES(DEFAULT 'http://www.w3schools.com')
SELECT x.q.query('declare default element namespace "http://www.w3schools.com";
	for $x in /xml return
	  <xml xmlns="http://www.w3schools.com">
	    { 
	    for $y in $x/col1 return $y
	    }
	    {
	    for $z in $x/bbb return
			<bbb>
			{
				for $u in $z/col2 return
				<col2>
				{
				for $e in $u/text() return $e
				}
				</col2>
			}
			</bbb>
	    }
	  </xml>')
FROM (SELECT (SELECT	1                     AS col1,
		rez.bbb
FROM	(SELECT	NULL AS col)  AS tbl   
		CROSS APPLY (
		      	SELECT	2 AS 'col2'
		      	FOR XML	PATH(''), TYPE
		      )               AS rez(bbb)
FOR XML	PATH('xml'), TYPE) q ) x
29 ноя 16, 20:27    [19948978]     Ответить | Цитировать Сообщить модератору
 Re: For Xml Path и default namespace  [new]
РСН
Member

Откуда:
Сообщений: 7
Коллеги доброе время суток. У меня обратная проблема, мне нужно прочитать данные. Есть XML.
DECLARE @xml XML, @idoc int;
SET @xml = '<ArrayOfEnumeration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Enumeration>
    <En_Name xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">ПО</En_Name>
    <En_Synonym xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">ПО</En_Synonym>
  </Enumeration>
  <Enumeration>
    <En_Name xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">Услуга</En_Name>
    <En_Synonym xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">Услуга</En_Synonym>
  </Enumeration>
  <Enumeration>
    <En_Name xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">Hardware</En_Name>
    <En_Synonym xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">Hardware</En_Synonym>
  </Enumeration>
  <Enumeration>
    <En_Name xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">Cloud</En_Name>
    <En_Synonym xmlns="https://1c.url.com/BIDictionary" xsi:type="xsd:string">Cloud</En_Synonym>
  </Enumeration>
</ArrayOfEnumeration>'

Мои попытки получить данные вот таким образом
EXEC sp_xml_preparedocument @idoc OUTPUT, @xml;

SELECT    *  
FROM OPENXML (@idoc, '/ArrayOfEnumeration/Enumeration',2)  
            WITH (En_Name  varchar(120) './*:En_Name',  
                  En_Synonym varchar(120) './*:En_Synonym');  

Не увенчались успехом смог, вытащить только вот так
select	
	b.value( 'text()[1]', 'varchar(100)') as En_Name
from	@xml.nodes('/ArrayOfEnumeration/Enumeration/*:En_Name') a(b)
Но мне нужны оба, подскажите как это сделать? Как мне проигнорировать element namespace или может наоборот указать его в явную, но где?
8 дек 16, 11:22    [19979530]     Ответить | Цитировать Сообщить модератору
 Re: For Xml Path и default namespace  [new]
invm
Member

Откуда: Москва
Сообщений: 9824
РСН
подскажите как это сделать?
exec sp_xml_preparedocument @idoc output, @xml, '<root xmlns:a="https://1c.url.com/BIDictionary"/>';

SELECT    *  
FROM OPENXML (@idoc, '/ArrayOfEnumeration/Enumeration',2)  
            WITH (En_Name  varchar(120) 'a:En_Name',  
                  En_Synonym varchar(120) 'a:En_Synonym');  
8 дек 16, 11:52    [19979729]     Ответить | Цитировать Сообщить модератору
 Re: For Xml Path и default namespace  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8805
РСН,
select	
	b.value( './*:En_Name[1]', 'varchar(100)') as En_Name,
	b.value( './*:En_Synonym[1]', 'varchar(100)') as En_Synonym
from	@xml.nodes('/ArrayOfEnumeration/Enumeration') a(b)
8 дек 16, 11:53    [19979736]     Ответить | Цитировать Сообщить модератору
 Re: For Xml Path и default namespace  [new]
РСН
Member

Откуда:
Сообщений: 7
invm, Владислав Колосов
Спасибо, два дня уже мучаюсь
select	
	b.value( './*:En_Name[1]', 'varchar(100)') as En_Name,
	b.value( './*:En_Synonym[1]', 'varchar(100)') as En_Synonym
from	@xml.nodes('/ArrayOfEnumeration/Enumeration') a(b)


Пробовал почти такую конструкцию, но с точкой тупанул. XML только осваиваю. :) Еще раз спасибо.
8 дек 16, 12:06    [19979795]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить