Может быть немного проще:
SELECT x.n.value('.', 'nvarchar(20)') as 'Name'
FROM @result.nodes('/A
/B
/*[local-name() =sql:variable("@NodePath")]
/@*[local-name()=sql:variable("@NodeVariable")]') x(n)
Вкратце идея:
- Погрузитесь ниже
<B>
(или используйте глубокий поиск с //
, если вы можете быть уверены, что <C>
не будет в любом другом месте) - Найдите любой элемент с заданным именем
- выберите атрибут с заданным именем (атрибуты являются одноэлементными для каждого элемента по определению)
- используйте
value()
на текущем узле , чтобы вернуть содержимое.
Что может мешать этому: множественные случаи из <C>
ниже <B>
ОБНОВЛЕНИЕ Некоторые дополнения к XPath и local-name()
Просто попробуйте следующее:
declare @result xml =
N'<A>
<B>
<C name="Name01"/>
</B>
<TheSecondInA />
<B>
<C name = "Name02"/>
</B>
<OneMore someAttr="x" oneMoreAttr="y" theLastAttr="z" >SomeText</OneMore>
</A>';
SELECT @result.value('local-name((//TheSecondInA)[1])','varchar(100)')
,@result.value('local-name((/A/*[2])[1])','varchar(100)')
,@result.value('local-name(/A[1]/*[2])','varchar(100)')
,@result.value('local-name((//*[@someAttr]/@*[2])[1])','varchar(100)')
,@result.value('local-name((/A/OneMore/@*[3])[1])','varchar(100)')
,@result.value('local-name((/A/OneMore/@*[last()])[1])','varchar(100)')
,@result.value('local-name((/A/OneMore/text())[1])','varchar(100)')
,@result.value('local-name((/DoesNotExist)[1])','varchar(100)')
Как видите, функция local-name()
должен получить singleton XPath .
- глубокий поиск переходит к первому появлению именованного узла
- То же самое возвращается вторым элементом ниже
<A>
- Нам этот
(SomeXpath)[1]
не нужен, если сам путь гарантирует возврат синглтона. - Точно так же мы можем выбрать третий атрибут на заданном пути
- Чтобы получить самый последний атрибут (или элемент), мы можем использовать
last()
- Если текущий узел является узлом
text()
или если элемент не существует, мы возвращаем пустую строку.
Подсказка: с похожими выражениями XPath вы можете использовать .value()
для получения локального содержимого, .exist()
для проверки наличия (или его отсутствия) и изменения заданного местоположения ...