我正在尝试从以下XML文档中查询单词Simple
。
该列为xml
数据类型,列名为InstanceSecurity
。
<InstanceSecurity>
<Folder>
<Authorization Mode="Simple">
<Deny PrivilegeCode="Create" />
<Deny PrivilegeCode="Delete" />
<Deny PrivilegeCode="Edit" />
<Deny PrivilegeCode="Read" />
<Deny PrivilegeCode="View" />
<Deny PrivilegeCode="Print" />
<Allow PrivilegeCode="All" EntityType="Personnel" EntityVal="5bc2" />
<Allow PrivilegeCode="All" EntityType="Personnel" EntityVal="f85b" />
</Authorization>
</Folder>
</InstanceSecurity>
我试过了:
Select InstanceSecurity.query('/InstanceSecurity/Folder/Authorization[@Mode="Simple"]') AS SecuredMode
FROM Cases
和
SELECT *
FROM Cases
WHERE InstanceSecurity.value('(/InstanceSecurity/Folder/Authorization/Mode)[1]','nvarchar(100)') like '%'
两者都没有返回任何内容
我看过的大多数示例都有一个开始和结束标记,比如
<item id="a">a is for apple</item>
不确定这是否会影响查询方式。
任何帮助都将不胜感激。
答案 0 :(得分:1)
了解您希望从XML中选择哪些内容非常重要。 元素和属性 - 以及元素标记text()
节点之间的浮动文本。执行此操作以查看原则:
DECLARE @xml XML=
N'<root>
<AnElement ID="1" AnAttribute="The attribute''s content">The element''s content</AnElement>
<AnElement ID="2" AnAttribute="Only the attribute" />
<AnElement ID="3">Text only</AnElement>
<AnElement ID="4" AnAttribute="nested children">
<child>This is the child''s content</child>
<child>One more child</child>
</AnElement>
<AnElement ID="5" AnAttribute="nested children">
This is text 1 within the element
<child>This is the child''s content</child>
This is text 2 within the element
<child>One more child</child>
This is text 3 within the element
</AnElement>
</root>';
SELECT elmt.value(N'@ID',N'int') ID
,elmt.value(N'@AnAttribute',N'nvarchar(250)') TheAttribute
,elmt.value(N'text()[1]',N'nvarchar(250)') TheFirstText
,elmt.value(N'text()[2]',N'nvarchar(250)') TheSecondText
,elmt.value(N'child[2]/text()[1]',N'nvarchar(250)') TheFirstTextWithinChild2
,elmt.value(N'.',N'nvarchar(250)') AS FullNodeContent
FROM @xml.nodes(N'/root/AnElement') AS A(elmt);
提示:尝试选择最后一个(value(N'.'),N'nvarchar(250)'
)并将输出发送到纯文本。这包括空格和换行符!
text()
(一个元素中可能有更多text()
个节点!)只是另一种节点,没有周围的标签。
您的尝试(略有变化)
选择 @ xml.query( '/ InstanceSecurity /文件夹/授权[@模式= “简单”]')
这将返回所有<Authorization>
个节点(xml类型!),其中属性“Mode”的内容为“Simple”
选择 @ xml.value( '(/ InstanceSecurity /文件夹/授权/ @模式)[1]', '为nvarchar(100)')
(你在“模式”之前忘记了@
!)
返回属性的值。在上面的例子中,这是“简单”
我真的不知道你想要什么,但下列之一应该指明你的方式
- 返回给定路径的属性@Mode
的第一个值
SELECT InstanceSecurity.value(N'(/InstanceSecurity/Folder/Authorization/@Mode)[1]',N'nvarchar(250)')
FROM Cases;
- 如果您的XML可能包含多个<Authorization>
,则会返回其所有@Mode
属性
SELECT auth.value(N'@Mode',N'nvarchar(250)')
FROM Cases
OUTER APPLY InstanceSecurity.nodes(N'/InstanceSecurity/Folder/Authorization') AS A(auth);
- 如果<Authorization>
是“简单”的所有@Mode
元素,则返回 - 如果很多 -
SELECT auth.query(N'.')
FROM Cases
OUTER APPLY InstanceSecurity.nodes(N'/InstanceSecurity/Folder/Authorization[@Mode="Simple"]') AS A(auth);
- 这会返回所有表格的行,其中至少有一个@Mode
的值为“简单”
SELECT *
FROM Cases
WHERE InstanceSecurity.exist(N'/InstanceSecurity/Folder/Authorization[@Mode="Simple"]')=1
最终提示:您可以使用XQuery
或sql:variable("@VarName")
替换sql:column("ColumnName")
中的文字值。
答案 1 :(得分:0)
试试这个
SELECT * FROM Cases
WHERE InstanceSecurity.value('(/InstanceSecurity/Folder/Authorization/@Mode)[1]','varchar(100)') = 'Simple'