XQuery 节点按值然后是它的兄弟节点
XQuery Node By Value Then Its Sibling
<a>
<b>111</b>
<c>AAA</c>
<b>222</b>
<c>BBB</c>
<b>333</b>
<c>CCC</c>
</a>
以上值可在 SQL 服务器的 XML 类型列中找到。
我想查找位于节点之后且值为“111”的节点的值。这可以使用 XQuery 完成吗?
到目前为止我有:
SELECT X.Y.value('('b[.="111"])[1]', 'varchar(10)') AS 'MyColumn'
FROM DBTable
CROSS APPLY DocXml.nodes('/a') AS X(Y);
这让我获得了第一个节点,但我无法获得同级节点。
不幸的是SQL服务器不支持兄弟轴,这会让这更简单。
相反,您需要执行以下操作
- 使用
let
将 b
节点保存到变量中
- 使用
*
取根的所有节点,通过检查每个节点是否跟在b
之后进行过滤,return第一个
- 请注意,您应该使用
text()
获取节点的内部文本,而不是依赖隐式转换。
SELECT
x1.a.value('let $b := b[text() = "111"][1] return (*[. >> $b]/text())[1]','varchar(100)')
FROM DBTable t
CROSS APPLY t.DocXml.nodes('/a') x1(a);
<a>
<b>111</b>
<c>AAA</c>
<b>222</b>
<c>BBB</c>
<b>333</b>
<c>CCC</c>
</a>
以上值可在 SQL 服务器的 XML 类型列中找到。
我想查找位于节点之后且值为“111”的节点的值。这可以使用 XQuery 完成吗?
到目前为止我有:
SELECT X.Y.value('('b[.="111"])[1]', 'varchar(10)') AS 'MyColumn'
FROM DBTable
CROSS APPLY DocXml.nodes('/a') AS X(Y);
这让我获得了第一个节点,但我无法获得同级节点。
不幸的是SQL服务器不支持兄弟轴,这会让这更简单。
相反,您需要执行以下操作
- 使用
let
将 - 使用
*
取根的所有节点,通过检查每个节点是否跟在b
之后进行过滤,return第一个 - 请注意,您应该使用
text()
获取节点的内部文本,而不是依赖隐式转换。
b
节点保存到变量中
SELECT
x1.a.value('let $b := b[text() = "111"][1] return (*[. >> $b]/text())[1]','varchar(100)')
FROM DBTable t
CROSS APPLY t.DocXml.nodes('/a') x1(a);