TSQL Parse XML с пространством имен - PullRequest
0 голосов
/ 14 октября 2019

Я пытаюсь проанализировать некоторые xml, которые хранятся в базе данных внутри хранимой процедуры. Процедура должна вернуть 2 столбца, id и значение. Я только часть пути через это, я застрял на том факте, что я не могу перечислить даже список узлов "Setting".

declare @PolicySettingsXml xml

set @PolicySettingsXml = '<?xml version="1.0" encoding="utf-8"?>
<Policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.myurl.com/app/Policies">
  <Setting id="VendorInfo0">
    <string>fsdfdsfds</string>
  </Setting>
  <Setting id="VendorInfo1">
    <string />
  </Setting>
  <Setting id="VendorInfo2">
    <string />
  </Setting>
  <Setting id="SendSurchargeAsSeparateTransaction">
    <boolean>false</boolean>
  </Setting>
  <Setting id="VendorSurchargeInfo0">
    <string />
  </Setting>
  <Setting id="VendorSurchargeInfo1">
    <string />
  </Setting>
  <Setting id="VendorSurchargeInfo2">
    <string />
  </Setting>
</Policy>'



select T.c.query('string') as value, T.c.query('@id') as id from @PolicySettingsXml.nodes('/Policy/Setting') T(c)

Я получаю сообщение об ошибке "XQuery[query ()]: атрибут может не отображаться за пределами элемента: «Я ожидаю увидеть:

id                                 |    value
VendorInfo0                        | fsdfdsfds
VendorInfo1                        | <null>  
VendorInfo2                        | <null>  
SendSurchargeAsSeparateTransaction | <null>
VendorSurchargeInfo1               | <null>  
VendorSurchargeInfo2               | <null>  

1 Ответ

0 голосов
/ 14 октября 2019

Первая проблема связана с синтаксисом. Это:

from PSXML.x.nodes('/*:Policy/*:Setting') T(c);

должно быть:

from (VALUES(@PolicySettingsXml)) AS PSXML(x)
CROSS APPLY PSXML.x.nodes('/*:Policy/*:Setting') T(c);

Для того, что вы делаете, вы можете использовать метод value для столбца id.

select
  id      = T.c.value('(@id)[1]', 'varchar(100)'),
  [value] = T.c.query('(*:string/text())[1]')
from (VALUES(@PolicySettingsXml)) AS PSXML(x)
CROSS APPLY PSXML.x.nodes('/*:Policy/*:Setting') T(c);

Обратите внимание, что я изменяю пространствам имен, используя синтаксис «все пространства имен»: * : Объект . Поиск в Google «пространства имен SQL Server T-SQL XML» покажет вам, как вы должны это сделать. Я обманул из-за нехватки времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...