Попробуйте так:
- ваше объявление
declare @text varchar(max)
set @text = N'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queryEE xmlns="http://xx.gob.gcaba.xx/">
<codeEE xmlns="">xxxx</codeEE>
</queryEE>
</s:Body>
</s:Envelope>'
declare @x xml
set @x = cast(@text as xml);
- запрос
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS s
,'http://xx.gob.gcaba.xx/' AS innerDflt)
select @x.value('(/s:Envelope/s:Body/innerDflt:queryEE/codeEE/text())[1]','nvarchar(100)');
Некоторый фон:
ВашXML немного странно смотрит на пространства имен ... если конструкция находится под вашим контролем, стоит начать здесь.
Существует пространство имен s:
для определения <Envelope>
и <Body>
,Пока это нормально. Но тогда элемент <queryEE>
определяет пространство имен по умолчанию (без префикса!), А встроенный <codeEE>
определяет другое (но пустое!) Пространство имен по умолчанию.Я почти уверен, что это пустое пространство имен создается в запросе путем объединения XML-файлов ...
пространство имен по умолчанию сообщает движку, что все узлы без определенногопрефикс живет в пределах этого пространства имен.Поэтому мы должны решить эту проблему.
Мой код использует WITH XMLNAMESPACES
для объявления всех пространств имен, встречающихся в XML.В отличие от исходного XML, я определяю префикс (innerDflt
) для первого пространства имен по умолчанию.Это означает, что мы можем обратиться к <innerDflt:queryEE>
.Встроенный элемент не нуждается в пространстве имен.Он живет в пустом пространстве имен по умолчанию (=> no).
Все это говорит, я просто хочу указать, что вы также можете использовать подстановочный знак:
select @x.value('(/*:Envelope/*:Body/*:queryEE/*:codeEE/text())[1]','nvarchar(100)')
И выможет даже использовать глубокий поиск
select @x.value('(//*:codeEE/text())[1]','nvarchar(100)')
Но общий совет: будьте настолько конкретны, насколько это возможно.