Вот простой пример:
declare @myXml xml
set @myXML = '
<root>
<line id="1"/>
<line id="2"/>
<line id="3"/>
</root>'
select t.c.query('.')
from @myXml.nodes('/root/line') t(c)
Как и ожидалось, я возвращаю три строки, которые выглядят так:
<line id="1" />
Однако, когда XML объявляет свое пространство имен (даже просто xmlns по умолчанию), вам также необходимо указать это пространство имен в SQL, иначе ваш набор результатов окажется пустым. Я знаю два способа: оператор declare в вызове метода nodes () или оператор с xmlnamespaces. Воспользуемся последним:
declare @myXml xml
set @myXML = '
<root xmlns="urn:somename">
<line id="1"/>
<line id="2"/>
<line id="3"/>
</root>';
with xmlnamespaces(default 'urn:somename')
select t.c.query('.')
from @myXml.nodes('/root/line') t(c)
Хотя сейчас я получаю результаты, в них есть определенная странность. Указанное пространство имен добавляется как "p1" вместо значения по умолчанию. Итак, мой результат выглядит так:
<p1:line xmlns:p1="urn:somename" id="1" />
В этой статье Technet, раздел B. Объявление пространства имен по умолчанию показывает, чего я пытаюсь достичь, но я получаю результат, показанный в D. Создание с использованием пространств имен по умолчанию. Поскольку мой пример не очень похож на последний, я не понимаю, почему я получаю эти префиксы.
Обновление: для полноты изложения это дает точно такой же симптом, что и синтаксис with xmlnamespaces:
select t.c.query('.')
from @myXml.nodes('declare default element namespace "urn:somename";/root/line') t(c)