Как получить дочерний элемент xmlelement в sql-запросе без его имени?

#xpath #xquery-sql

#xpath #xquery-sql

Вопрос:

В XML-столбце sql server у меня есть xml, подобный этому:

 <Test>  
    <Operations>
        <Operations type="OperationSend">
            <OperationSend>                             
                <ToCompanyId>1</ToCompanyId>
                <Date>2011-05-01T00:00:00</Date>                
            </OperationSend>
        </Operations>
        <Operations type="OperationSell">
            <OperationSell>
                <ToCompanyId>33</ToCompanyId>
                <Amount>12</Amount>
            </OperationSell>
        </Operations>
        <Operations type="OperationEdit">
            <OperationEdit>
                <ToCompanyId>12</ToCompanyId>
                <Date>2011-11-01T00:00:00</Date>    
            </OperationEdit>
        </Operations>
    </Operations>
</Test>
  

Мне нужно взять идентификатор ToCompanyId из последней операции (12). Я пришел к чему-то вроде этого. Что должно быть в??? когда может быть любой тип операции с ToCompanyId.

 select testxml.query('(/Test/Operations/Operations)[last()]/???/ToCompanyId') from dbo.MyXmlTable
  

Комментарии:

1. Я рекомендую вам принять лучший ответ — в данном конкретном случае он дан @Mikael Eriksson.

Ответ №1:

Вы можете использовать *

 select testxml.query('(/Test/Operations/Operations)[last()]/*/ToCompanyId').value('.', 'int')
from MyXmlTable
  

Ответ №2:

Поместите node() вместо ???

node() сопоставляет все узлы любого типа

Комментарии:

1. Вам нужно подумать о более точном тестировании узла, чем просто node() . Подсказка: Смотрите ответ Микаэля Эрикссона.

Ответ №3:

Предполагая, что вы настроили свой xml как переменную с именем @x, тогда вот как получить ваш 12.

 select  x.header.value('.', 'int') 
                from @x.nodes('//Test/Operations/Operations[last()]/OperationSend/ToCompanyId')
                 as x(header) 
  

запрос будет немного отличаться для получения из столбца таблицы, но XPATH будет тем же самым.

 select testxml.query('//Test/Operations/Operations[last()]/OperationSend/ToCompanyId') from dbo.MyXmlTable