SQL Server XML.value上下文节点

时间:2016-01-31 18:15:11

标签: sql-server xml xpath

我向用户提供我们工作的工具,计算变量的可能性。值由给定的XPath表达式计算。在.Net中,使用Saxon库,可以通过在要计算的值的上下文中执行XPath表达式来计算值。

示例XML:

@data = '<Object>
  <Parameters>
    <Parameter Name="a">2</Parameter>
    <Parameter Name="b">5</Parameter>
    <Parameter Name="c"/>
  </Parameters>
</Object>'

参数上下文中的XPath表达式,名称为&#34; c&#34;:

../Parameter[@Name="a"]/text() + ../Parameter[@Name="b"]/text()

这将导致7;)

我喜欢在SQL Server上执行XPath表达式,但现在想知道如何更改XML类型的上下文节点?

一种可能性是我在更改上下文的表达式前面添加了一个XPath,但是如果可能的话还没有找到。查询可能看起来像:

/<go to node variable "c" and make this the context node>

../Parameter[@Name="a"]/text() + ../Parameter[@Name="b"]/text()

有人有好主意吗?

2 个答案:

答案 0 :(得分:1)

使用SQL Server的XQuery,您可以声明XQuery变量,例如$p来引用目标父元素,即<Parameters>,其中找到具有属性Name="c"的子元素。然后,您可以使用$p作为上下文元素进行进一步的XPath / XQuery处理:

declare @data XML = '<Object>
  <Parameters>
    <Parameter Name="a">2</Parameter>
    <Parameter Name="b">5</Parameter>
    <Parameter Name="c"/>
  </Parameters>
</Object>'

SELECT @data.value('
    let $p := /Object/Parameters[Parameter/@Name="c"]
    return ($p/Parameter[@Name="a"])[1] + ($p/Parameter[@Name="b"])[1]
','int') AS Result

<强> sqlfiddle demo

输出

7

答案 1 :(得分:1)

你想要的是 - AFAIK - 不可能......

尝试使用XPath表达式定义工作查询:

顺便说一下:你的例子在两个方面是错误的:XML中的Attributs没有@ - 标记,而结束参数标签缺少最终的&#34; s&#34; ... < / p>

DECLARE @data XML=
'<Object>
  <Parameters>
    <Parameter Name="a">2</Parameter>
    <Parameter Name="b">5</Parameter>
    <Parameter Name="c"/>
  </Parameters>
</Object>';

--This will not work, because your parts are not singleton
--SELECT Context.Node.value('../Parameter[@Name="a"]/text() + ../Parameter[@Name="b"]/text()','int')
--FROM @data.nodes('/Object/Parameters/Parameter[@Name="c"]') AS Context(Node);

--This works, because I framed both parts with (...)[1]
SELECT Context.Node.value('(../Parameter[@Name="a"]/text())[1] + (../Parameter[@Name="b"]/text())[1]','int')
FROM @data.nodes('/Object/Parameters/Parameter[@Name="c"]') AS Context(Node);

但是可能有一种解决方法,但它非常黑客且不可靠:

存储过程创建一个根据您的参数构建的动态sql语句并执行它。

您的必须不会更改的 XPath表达式将会更改为+左侧和右侧的空白(以及{{} 1}},-*)被替换为返回单例表达式。我不知道计算有多复杂。看看......

/