在 SQL Server 中的 XML 文档中查找节点顺序 [英] Finding node order in XML document in SQL Server

查看:40
本文介绍了在 SQL Server 中的 XML 文档中查找节点顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 XML 文档中找到节点的顺序?

How can I find the order of nodes in an XML document?

我有一个这样的文件:

<value code="1">
    <value code="11">
        <value code="111"/>
    </value>
    <value code="12">
        <value code="121">
            <value code="1211"/>
            <value code="1212"/>
        </value>
    </value>
</value>

我正试图把这个东西放到一个像

and I'm trying to get this thing into a table defined like

CREATE TABLE values(
    code int,
    parent_code int,
    ord int
)

保留 XML 文档中值的顺序(它们不能按代码排序).我想说

Preserving the order of the values from the XML document (they can't be ordered by their code). I want to be able to say

SELECT code 
FROM values 
WHERE parent_code = 121 
ORDER BY ord

结果应该是确定性的

code
1211
1212

我试过了

SELECT 
    value.value('@code', 'varchar(20)') code, 
    value.value('../@code', 'varchar(20)') parent, 
    value.value('position()', 'int')
FROM @xml.nodes('/root//value') n(value)
ORDER BY code desc

但它不接受 position() 函数('position()' 只能在谓词或 XPath 选择器中使用).

But it doesn't accept the position() function ('position()' can only be used within a predicate or XPath selector).

我想以某种方式是可能的,但是如何?

I guess it's possible some way, but how?

推荐答案

您可以通过计算每个节点之前的兄弟节点的数量来模拟 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.

这篇关于在 SQL Server 中的 XML 文档中查找节点顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆