Я играю с SQL и XML. У меня есть столбец в нашей базе данных (properties), где хранится XML.

Пример этого XML выглядит так:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.xyz.de/activerepository/fileprops">
  <props>
    <prop ns="ARM:" elem="_NoFilter">
      <value xsi:type="xsd:boolean">true</value>
    </prop>
    <prop ns="DAV:" elem="displayname">
      <value xsi:type="xsd:string">Some text in it</value>
    </prop>
    <prop ns="DAV:" elem="getcontenttype">
      <value xsi:type="xsd:string">message/rfc822</value>
    </prop>
    <prop ns="DAV:" elem="creationdate">
      <value xsi:type="xsd:dateTime">2017-01-02T09:38:28.1278078</value>
    </prop>
  </props>
</root>

Я написал запрос, в котором я получаю все реквизиты этой XML-структуры.

;WITH XMLNAMESPACES(DEFAULT 'http://www.xyz.de/activerepository/fileprops')
SELECT 
    cast(properties as xml).query('root/props/prop'),
    *
FROM   tm_cas_files (nolock)
where  id = 'A7ED7D99-8CDB-47F6-8EF5-18E7FCB97F28'

Этот запрос работает нормально, но я получаю все узлы структуры XML.

Результат этого запроса выглядит так:

<p1:prop xmlns:p1="http://www.xyz.de/activerepository/fileprops" ns="ARM:" elem="_NoFilter">
  <p1:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:boolean">true</p1:value>
</p1:prop>
<p2:prop xmlns:p2="http://www.xyz.de/activerepository/fileprops" ns="DAV:" elem="displayname">
  <p2:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">Some text in it</p2:value>
</p2:prop>
<p3:prop xmlns:p3="http://www.xyz.de/activerepository/fileprops" ns="DAV:" elem="getcontenttype">
  <p3:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">message/rfc822</p3:value>
</p3:prop>
<p4:prop xmlns:p4="http://www.xyz.de/activerepository/fileprops" ns="DAV:" elem="creationdate">
  <p4:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:dateTime">2017-01-02T09:38:28.1278078</p4:value>
</p4:prop>

Как я могу получить только конкретный узел этого XML?

Я уже тестировал этот запрос (например, чтобы получить узел "_NoFilter"), но этот запрос SQL не возвращает / пустой результат:

;WITH XMLNAMESPACES(DEFAULT 'http://www.xyz.de/activerepository/fileprops')
SELECT 
    cast(properties as xml).query('root/props/prop[elem="_NoFilter"]'),
    *
FROM   tm_cas_files (nolock)
where  id = 'A7ED7D99-8CDB-47F6-8EF5-18E7FCB97F28'

Спасибо за вашу помощь!

2
dns_nx 3 Янв 2018 в 13:14

2 ответа

Лучший ответ

Если вам нужен только узел _NoFilter, вы можете использовать XPath, чтобы выбрать только этот.

/root/props/prop[@elem="_NoFilter"]

Или, может быть, даже

/root/props/prop[@elem="_NoFilter"]/value

Стенограмма :

//prop[@elem="_NoFilter"]/value
2
Tomalak 3 Янв 2018 в 11:02

Если вы уже знаете индекс элемента, один из способов -

;WITH XMLNAMESPACES(DEFAULT 'http://www.xyz.de/activerepository/fileprops')
SELECT 
    @xml.query('root/props/prop[2]')

Или лучше вы можете использовать следующий запрос SQL XML

;WITH XMLNAMESPACES(DEFAULT 'http://www.xyz.de/activerepository/fileprops')
select
    val.value('.','nvarchar(100)') as [PropValue]
from @xml.nodes('/root/props/prop[@elem="_NoFilter"]/value') as p(val)

enter image description here

2
Eralper 3 Янв 2018 в 11:14