如何使用XQUERY从XML中提取属性的值?

时间:2015-07-12 16:36:48

标签: sql-server xquery-sql

CREATE TABLE SportsEvent
(ID INT, Name NVARCHAR(20), Results XML);
GO


DECLARE @Results XML=
'<Athletics>
  <Event ID="001" Name="100m">
    <Gold>John Doe</Gold>
    <Silver>Harry Smith</Silver>
    <Bronze>Kenneth Brown</Bronze>
  </Event>
  <Event ID="002" Name="High Jump">
    <Gold>Sarah Jones</Gold>
    <Silver>Janice Johnson</Silver>
    <Bronze>Alicia Armstrong</Bronze>
  </Event>
</Athletics>'
INSERT INTO SportsEvent
VALUES(1, 'AthleticsDay', @Results);

SELECT * FROM SportsEvent;

如果我想根据事件ID提取元素,没问题:

SELECT Results.query('(/Athletics/Event[@ID="001"]/Gold)')
FROM SportsEvent
WHERE ID = 1

我可以使用相对引用做同样的事情:

SELECT Results.query('(Athletics/Event)[1]')
FROM SportsEvent
WHERE ID = 1

但是,如果我想根据相对或绝对来拉取事件名称?:

SELECT Results.query('(Athletics/Event[@Name])[@ID="001"]')
FROM SportsEvent
WHERE ID = 1


SELECT Results.query('(Athletics/Event[@Name])[1]')
FROM SportsEvent
WHERE ID = 1

...两者都会带回该事件的所有数据。

我尝试使用值方法:

SELECT Results.value('(/Athletics/Event/@Name)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1

...但这只适用于相对参考,即在这种情况下是XML中的第一组结果。

如果我想指定事件ID并仅返回事件名称(作为XML片段或数据/值),该怎么办?

1 个答案:

答案 0 :(得分:2)

好吧,对某些人来说(很多人?)这看起来非常明显,但我会发布我的asnwer,以防止其他人花费一些令人沮丧的几个小时的时间绕圈子(就像我刚刚做的那样) ...

SELECT Results.value('(/Athletics/Event[@ID="001"]/@Name)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1

SELECT Results.value('(/Athletics/Event[@Name="100m"]/@ID)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1

SELECT Results.value('(/Athletics/Event[@Name="High Jump"]/@ID)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1

SELECT Results.value('(/Athletics/Event[@ID="002"]/@Name)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1

从我可以确定的是,您不能使用查询方法仅返回属性的值,查询必须使用不允许的元素之外的属性来编写。

然而,你可以使用如下的查询方法 - 路径末尾的'[1]'(单例)不是强制性的(它们与值方法一起使用)。你将得到的是包含指定属性的整个片段。

SELECT Results.query('(/Athletics/Event[@ID="002"][@Name])[1]')
FROM SportsEvent
WHERE ID = 1

SELECT Results.query('(/Athletics/Event[@Name="100m"][@Name])[1]')
FROM SportsEvent
WHERE ID = 1

希望这有助于某人。

欢迎任何评论,更正或补充。 感谢。