在 SQL Server 中的 XML 文档中查找节点顺序 [英] Finding node order in XML document in SQL Server
问题描述
如何在 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-likecurrent()
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屋!