【发布时间】:2017-09-20 16:20:37
【问题描述】:
使用 xpath child.value('for $i in . return count(../../*[. << $i])', 'int') 将通过计算父节点中出现在当前节点之前的相邻节点的数量,为我提供 XML 中节点的索引。这很好用,但我需要按 NODE-NAME 分组\重置索引计数。
(在下面的示例中,我将索引作为 varchar 查询,以便将字符串与其内容连接起来)
DECLARE @x XML = '
<Vitals>
<BP>
<Value>120/80</Value>
<Time>02:00:05</Time>
</BP>
<BP>
<Value>140/90</Value>
<Time>02:10:01</Time>
</BP>
<BP>
<Value>120/80</Value>
<Time>02:15:05</Time>
</BP>
<HR>
<Value>80</Value>
<Time>02:00:12</Time>
</HR>
<HR>
<Value>84</Value>
<Time>02:10:12</Time>
</HR>
</Vitals>'
SELECT '/' + child.value('local-name(../..)', 'varchar(max)') + '/' + child.value('local-name(..)', 'varchar(max)') + '[' + child.value('for $i in . return count(../../*[. << $i])', 'varchar(max)') + ']' AS NodePath
,child.value('local-name(.)', 'varchar(max)') AS NodeName
,child.value('.', 'varchar(max)') AS NodeValue
FROM (
SELECT @x AS import_data
) i
CROSS APPLY i.import_data.nodes('/Vitals/*/*') AS nodes(child)
WHERE LEN(cast(child.query('./*') AS VARCHAR(max))) = 0
ORDER BY child.value('for $i in . return count(../../*[. << $i])', 'int')
返回:
/Vitals/BP[1] Value 120/80
/Vitals/BP[1] Time 02:00:05
/Vitals/BP[2] Value 140/90
/Vitals/BP[2] Time 02:10:01
/Vitals/BP[3] Value 120/80
/Vitals/BP[3] Time 02:15:05
/Vitals/HR[4] Value 80
/Vitals/HR[4] Time 02:00:12
/Vitals/HR[5] Value 84
/Vitals/HR[5] Time 02:10:12
如您所见,BP[x] 索引是正确的,但是当节点名称从“BP”更改为“HR”时,索引会继续增加,而HR[x] 索引是错误的。我需要它来重置索引以获取元素的 PROPER XPATH 索引(同名元素的索引),而不仅仅是父元素的索引。我需要我的输出看起来像这样:
/Vitals/BP[1] Value 120/80
/Vitals/BP[1] Time 02:00:05
/Vitals/BP[2] Value 140/90
/Vitals/BP[2] Time 02:10:01
/Vitals/BP[3] Value 120/80
/Vitals/BP[3] Time 02:15:05
/Vitals/HR[1] Value 80
/Vitals/HR[1] Time 02:00:12
/Vitals/HR[2] Value 84
/Vitals/HR[2] Time 02:10:12
有没有更好的方法来获得我正在寻找的东西?如何从我的节点获取正确的 XPATH 索引?
【问题讨论】:
标签: sql sql-server xml tsql xpath