像我之前的问题一样,我想通过sql查询提取所有“名称”和路径标记(privilegedUsers->条目->条目->名称)。 谢谢
<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>
答案 0 :(得分:0)
您的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')
答案 1 :(得分:0)
您可以尝试
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);