Xpath查询名称而不是索引

时间:2013-01-28 12:21:00

标签: sql-server tsql xpath

我在sql server的xml列中有以下xml,它与id列在一个表中 -

<ArrayOfExtVar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ExtVar>
    <Name xsi:type="xsd:string">Rate Code</Name>
    <Value xsi:type="xsd:string">E46</Value>
  </ExtVar>
  <ExtVar>
    <Name xsi:type="xsd:string">Middle Name</Name>
    <Value xsi:type="xsd:string">Henry</Value>
  </ExtVar>
</ArrayOfExtVar>

我有以下XPath -

SELECT CustID, 
ExtVars.value('(/ArrayOfExtVar/ExtVar/Value)[1]', 'Nvarchar(max)') AS RateCode,
ExtVars.value('(/ArrayOfExtVar/ExtVar/Value)[2]', ''Nvarchar(max)') AS MiddleInitial 
FROM dbo.Customer

这很棒,但我真正想做的是通过&#39; Name&#39;来查询xml。而不是索引([1]),因为这些可能会不时以不同的顺序存储。

基本上我需要知道的是如何通过&#39; Name&#39;的值来查询?像 -

'(/ArrayOfExtVar/ExtVar/Value)[Rate Code]'

我可以将一个属性添加到ExtVars节点并对其进行查询吗?

4 个答案:

答案 0 :(得分:1)

这听起来像你想要的

/ArrayOfExtVar/ExtVar[Name = 'Rate Code']/Value

答案 1 :(得分:0)

你是否想要做这样的事情:

DECLARE @input TABLE (ID INT, ExtVars XML)

INSERT INTO @input VALUES(1, '<ArrayOfExtVar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ExtVar>
    <Name xsi:type="xsd:string">Rate Code</Name>
    <Value xsi:type="xsd:string">E46</Value>
  </ExtVar>
  <ExtVar>
    <Name xsi:type="xsd:string">Middle Name</Name>
    <Value xsi:type="xsd:string">Henry</Value>
  </ExtVar>
</ArrayOfExtVar>')

SELECT
    Name = ExtVar.value('(Name)[1]', 'varchar(50)'),
    [Value] = ExtVar.value('(Value)[1]', 'varchar(50)')
FROM
    @input
CROSS APPLY
    ExtVars.nodes('/ArrayOfExtVar/ExtVar') AS XTbl(ExtVar)
WHERE   
    ID = 1

返回如下输出:

enter image description here

当然,您可以为此添加基于名称的WHERE子句(“到达”XML以确定结果):

SELECT
    Name = ExtVar.value('(Name)[1]', 'varchar(50)'),
    [Value] = ExtVar.value('(Value)[1]', 'varchar(50)')
FROM
    @input
CROSS APPLY
    ExtVars.nodes('/ArrayOfExtVar/ExtVar') AS XTbl(ExtVar)
WHERE   
    ExtVar.value('(Name)[1]', 'varchar(50)') LIKE 'Rate%'   -- or whatever you want

答案 2 :(得分:0)

我不知道SQL Server的XPath实现是否支持父(..)运算符,但您可以尝试这样做:

/ArrayOfExtVar/ExtVar/Name[text()='Rate Code']/../Value

这会找到内部文本为Name的{​​{1}}节点,然后导航到其父节点,然后从那里转到它下面的'Rate Code'节点。


如果您可以添加Value作为Name节点的属性,那么会更容易:

示例XML:

ExtVar

的XPath:

...
<ExtVar name="Rate Code">
    <Value xsi:type="xsd:string">E46</Value>
</ExtVar>
...

答案 3 :(得分:0)

您也可以在谓词中执行轴步骤。

//ExtVar[Name eq 'Rate Code']/Value