Извлечение данных тега XML из столбца XML в MSSQL - PullRequest
0 голосов
/ 06 июня 2019

как и мой предыдущий вопрос, я хочу извлечь все теги "name" и path (privilegedUsers -> records -> entry -> name) с помощью SQL-запроса. * 1001 спасибо *

<Policy>
 <id>f3d25685-fb54-438d-a0e9-03e4ba5b555f</id>
 <name>SG</name>
 <description />
 <attributes>0</attributes>
 <parentPolicy>a7c603c0-8700-45ef-9165-c0134e292ee4</parentPolicy>
 <sharedPasswordRev>-1</sharedPasswordRev>
 <useShortChallengeResponse>false</useShortChallengeResponse>
 <settings>
 <privilegedUsers>
 <entries>
  <entry>
   <name>CEO</name>
   <path>CN=CEO,CN=Users,DC=sglab,DC=local</path>
   <uid>27C9C6AC9311424BB332CC5AB04B047D</uid>
   <serverName>192.168.7.201</serverName>
   <sid>S-1-5-21-3362085216-3357124804-2073486349-1108</sid>
   <type>user</type>
 </entry>
 <entry>
    <name>Administrator</name>
    <path>CN=Administrator,CN=Users,DC=sglab,DC=local</path>
    <uid>EBBC4D71CD68BE4BA49BC8B6DF01F954</uid>
    <serverName>192.168.7.201</serverName>
    <sid>S-1-5-21-3362085216-3357124804-2073486349-500</sid>
    <type>user</type>
   </entry>
 </privilegedUsers>
 <unknownAppsStrategy>EDITOR</unknownAppsStrategy>
</settings>
</Policy>

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Вы можете попробовать это

DECLARE @xml XML=
N'<Policy>
 <id>f3d25685-fb54-438d-a0e9-03e4ba5b555f</id>
 <name>SG</name>
 <description />
 <attributes>0</attributes>
 <parentPolicy>a7c603c0-8700-45ef-9165-c0134e292ee4</parentPolicy>
 <sharedPasswordRev>-1</sharedPasswordRev>
 <useShortChallengeResponse>false</useShortChallengeResponse>
 <settings>
 <privilegedUsers>
 <entries>
  <entry>
   <name>CEO</name>
   <path>CN=CEO,CN=Users,DC=sglab,DC=local</path>
   <uid>27C9C6AC9311424BB332CC5AB04B047D</uid>
   <serverName>192.168.7.201</serverName>
   <sid>S-1-5-21-3362085216-3357124804-2073486349-1108</sid>
   <type>user</type>
 </entry>
 <entry>
    <name>Administrator</name>
    <path>CN=Administrator,CN=Users,DC=sglab,DC=local</path>
    <uid>EBBC4D71CD68BE4BA49BC8B6DF01F954</uid>
    <serverName>192.168.7.201</serverName>
    <sid>S-1-5-21-3362085216-3357124804-2073486349-500</sid>
    <type>user</type>
   </entry>
 </entries>
 </privilegedUsers>
 <unknownAppsStrategy>EDITOR</unknownAppsStrategy>
</settings>
</Policy>';

- Запрос

SELECT @xml.value('(/Policy/id/text())[1]','uniqueidentifier') AS id
      ,@xml.value('(/Policy/name/text())[1]','nvarchar(max)') AS [name]
      --Use similar lines for all the other values below `<Policy>`
      ,prUsrEntry.value('(name/text())[1]','nvarchar(max)') AS PrivilegedUserName
      ,prUsrEntry.value('(path/text())[1]','nvarchar(max)') AS PrivilegedUserpath
      --Use similar lines for values within the given `<entry>`
FROM @xml.nodes('/Policy/settings/privilegedUsers/entries/entry') A(prUsrEntry);

Идея вкратце:

Мы используем прямые вызовы .value() для получениясвойства первого уровня непосредственно из @xml.Можно и немного легче читать, чтобы использовать nodes() или .query(), чтобы избежать повторного XPath, но это ухудшит производительность.

Затем мы используем FROM @xml.nodes(), чтобы получить производную таблицуповторяющиеся элементы.Каждый <entry> по указанному пути будет возвращен в виде строки в производной таблице со столбцом с типом XML, представляющим <entry> по этому пути.

Теперь Wen может использовать .value() для чтения вложенногоэлементы.Помните о относительном пути (без / до name).

Некоторые подсказки:

Ваш XML выглядит так, как будто он может содержать несколько различных <settings>.Вы можете использовать запрос, подобный этому, чтобы быть более общим:

SELECT @xml.value('(/Policy/id/text())[1]','uniqueidentifier') AS id
      ,@xml.value('(/Policy/name/text())[1]','nvarchar(max)') AS [name]
      --Use similar lines for all the other values below `<Policy>`
      ,prUsrEntry.value('(name/text())[1]','nvarchar(max)') AS PrivilegedUserName
      ,prUsrEntry.value('(path/text())[1]','nvarchar(max)') AS PrivilegedUserpath
      --Use similar lines for values within the given `<entry>`
FROM @xml.nodes('/Policy/settings') A(settings)
OUTER APPLY A.settings.nodes('privilegedUsers/entries/entry') B(prUsrEntry)
--Add more APPLYs to fetch values from other `<settings>` areas

Или даже что-то подобное этому полностью универсальному подходу

SELECT @xml.value('(/Policy/id/text())[1]','uniqueidentifier') AS id
      ,@xml.value('(/Policy/name/text())[1]','nvarchar(max)') AS [name]
      --Use similar lines for all the other values below `<Policy>`
      ,anySeeting.value('local-name(.)','nvarchar(max)') AS SettingName
      ,anyValue.value('local-name(.)','nvarchar(max)') AS ValueName
      ,anyValue.value('text()[1]','nvarchar(max)') AS NestedValue
FROM @xml.nodes('/Policy/settings') A(settings)
OUTER APPLY A.settings.nodes('*') B(anySeeting)
OUTER APPLY B.anySeeting.nodes('entries/entry/*') AS C(anyValue)

ОБНОВЛЕНИЕ

Это способсделать то же самое с данными таблицы:

SELECT YourXML.value('(/Policy/id/text())[1]','uniqueidentifier') AS id
      ,YourXML.value('(/Policy/name/text())[1]','nvarchar(max)') AS [name]
      --Use similar lines for all the other values below `<Policy>`
      ,prUsrEntry.value('(name/text())[1]','nvarchar(max)') AS PrivilegedUserName
      ,prUsrEntry.value('(path/text())[1]','nvarchar(max)') AS PrivilegedUserpath
      --Use similar lines for values within the given `<entry>`
FROM YourTable
OUTER APPLY YourXML.nodes('/Policy/settings/privilegedUsers/entries/entry') A(prUsrEntry);
0 голосов
/ 06 июня 2019

Ваш xml плохо сформирован.У вас нет закрывающего тега </entries>.

Когда я исправляю это, это ваш код:

declare @xml xml
set @xml=convert(xml,'<Policy>
 <id>f3d25685-fb54-438d-a0e9-03e4ba5b555f</id>
 <name>SG</name>
 <description />
 <attributes>0</attributes>
 <parentPolicy>a7c603c0-8700-45ef-9165-c0134e292ee4</parentPolicy>
 <sharedPasswordRev>-1</sharedPasswordRev>
 <useShortChallengeResponse>false</useShortChallengeResponse>
 <settings>
 <privilegedUsers>
 <entries>
  <entry>
   <name>CEO</name>
   <path>CN=CEO,CN=Users,DC=sglab,DC=local</path>
   <uid>27C9C6AC9311424BB332CC5AB04B047D</uid>
   <serverName>192.168.7.201</serverName>
   <sid>S-1-5-21-3362085216-3357124804-2073486349-1108</sid>
   <type>user</type>
 </entry>
 <entry>
    <name>Administrator</name>
    <path>CN=Administrator,CN=Users,DC=sglab,DC=local</path>
    <uid>EBBC4D71CD68BE4BA49BC8B6DF01F954</uid>
    <serverName>192.168.7.201</serverName>
    <sid>S-1-5-21-3362085216-3357124804-2073486349-500</sid>
    <type>user</type>
   </entry>
   </entries>
 </privilegedUsers>
 <unknownAppsStrategy>EDITOR</unknownAppsStrategy>
</settings>
</Policy>')

select @xml.query('/Policy/settings/privilegedUsers/entries/entry/name')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...