如何将多个XPath查询合并为一个

时间:2017-01-03 12:52:54

标签: sql-server xml xpath

我有一张这样的表

create table [Trades] (
    [Id] int not null
    ,[TradeXML] xml not null
    )

这里是TradeXML xml列的内容

<Trade>
  <Arg>
    <Name>Id</Name>
    <Data>
      <DataItem DataType="8">012345678</DataItem>
    </Data>
  </Arg>
  <Arg>
    <Name>Function</Name>
    <Data>
      <DataItem DataType="8">CapFloor</DataItem>
    </Data>
  </Arg>
  <Arg>
    <Name>Curve</Name>
    <Data>
      <DataItem DataType="8">EURCurve</DataItem>
    </Data>
  </Arg>
  <Arg>
    <Name>Rates</Name>
    <Data>
      <DataItem DataType="5">2.175</DataItem>
      <DataItem DataType="5">2.169</DataItem>
      <DataItem DataType="5">2.714</DataItem>
      <DataItem DataType="5">3.394</DataItem>
      <DataItem DataType="5">3.931</DataItem>
      <DataItem DataType="5">4.477</DataItem>
      <DataItem DataType="5">4.296</DataItem>
    </Data>
  </Arg>
  <Arg>
    <Name>Index</Name>
    <Data>
      <DataItem DataType="8">EURIBOR</DataItem>
    </Data>
  </Arg>
</Trade>

这个sql

select Node.Name.value('.', 'varchar(100)') Label
from Trades as t
cross apply t.TradeXML.nodes('//Arg/Name') Node(Name)

返回5行:

Id
Function
Curve
Rates
Index

这个sql

select Data.Name.value('.','varchar(100)') Value
from Trades as t
cross apply t.TradeXML.nodes('//Arg/Data/DataItem[1]') Data(Name)

返回5行:

012345678 
CapFloor 
EURCurve 
2.175 
EURIBOR 

和这个

select Attribute.Name.query('local-name(.)') Attribute
    ,Attribute.Name.value('.', 'varchar(100)') Value
from Trades as t
cross apply t.TradeXML.nodes('//@*') Attribute(Name)

返回11行:

DataType 8 
DataType 8 
DataType 8 
DataType 5 
DataType 5 
DataType 5 
DataType 5 
DataType 5 
DataType 5 
DataType 5 
DataType 8 

但我想要的是这个的组合(所以基本上是Name,(第一个)DataItem值和(第一个)DataItem的DataType属性的值),如下所示:

Id          012345678   8
Function    CapFloor    8
Curve       EURCurve    8
Rates       2.175       5
Index       EURIBOR     8

我已将其保存在rextester中以进行游戏。我试图自己组合,但没有设法得到正确的结果。 任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

Arg元素上粉碎XML,并从那里开始选择所需信息:

select 
    Node.Arg.value('Name[1]', 'varchar(100)') Label,
    Node.Arg.value('(Data/DataItem)[1]', 'varchar(100)') DataItem,
    Node.Arg.value('(Data/DataItem)[1]/@DataType', 'varchar(100)') DataType
from Trades as t
cross apply t.TradeXML.nodes('//Arg') Node(Arg)

<强> rextester demo