且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在 SQL Server 中的 XML 文档中查找节点顺序

更新时间:2022-06-11 06:17:15

您可以通过计算每个节点之前的兄弟节点的数量来模拟 position() 函数:

You can emulate the position() function by counting the number of sibling nodes preceding each node:

SELECT
    code = value.value('@code', 'int'),
    parent_code = value.value('../@code', 'int'),
    ord = value.value('for $i in . return count(../*[. << $i]) + 1', 'int')
FROM @Xml.nodes('//value') AS T(value)

这是结果集:

code   parent_code  ord
----   -----------  ---
1      NULL         1
11     1            1
111    11           1
12     1            2
121    12           1
1211   121          1
1212   121          2

工作原理:

  • for $i in . 子句定义了一个名为 $i 的变量,该变量包含当前节点 (.).这基本上是解决 XQuery 缺少类似 XSLT 的 current() 函数的一个技巧.
  • ../* 表达式选择当前节点的所有兄弟节点(父节点的子节点).
  • [.<<$i] 谓词将兄弟列表过滤到前面的列表 () 当前节点($i).
  • 我们count() 前面兄弟的数量,然后加1得到位置.这样,第一个节点(没有前面的兄弟节点)被分配了 1 的位置.
  • The for $i in . clause defines a variable named $i that contains the current node (.). This is basically a hack to work around XQuery's lack of an XSLT-like current() function.
  • The ../* expression selects all siblings (children of the parent) of the current node.
  • The [. << $i] predicate filters the list of siblings to those that precede (<<) the current node ($i).
  • We count() the number of preceding siblings and then add 1 to get the position. That way the first node (which has no preceding siblings) is assigned a position of 1.