不能使用交叉应用来粉碎XML数据

时间:2013-10-12 23:24:59

标签: xml tsql xpath

鉴于这个XML片段(VIN显然是假的)

<VehicleFeed>
  <Vehicle>
    <VIN>1234</VIN>
    <Equipment>
      <EquipmentDesc>1.1</EquipmentDesc>
      <EquipmentDesc>1.2</EquipmentDesc>
      <EquipmentDesc>1.3</EquipmentDesc>
    </Equipment>
  </Vehicle>
  <Vehicle>
    <VIN>2345</VIN>
    <Equipment>
      <EquipmentDesc>2.1</EquipmentDesc>
      <EquipmentDesc>2.2</EquipmentDesc>
      <EquipmentDesc>2.3</EquipmentDesc>
    </Equipment>
  </Vehicle>
</VehicleFeed>

What I really want is this result set

VIN  EquipmentDesc
---  -------------
1234 1.1
1234 1.2
1234 1.3
2345 2.1
2345 2.2
2345 2.3

我在一个名为@xdata的var中有xml数据。下面的代码是我认为可行的,但是它将所有设备值连接成一列数据,而不是将它们分成几行。

select t.c.value('VIN[1]', 'varchar(20)') as VIN
     , t1.c1.value('.', 'varchar(80)') as EquipDesc
from @xdata.nodes('//VehicleFeed/Vehicle') as t(c)
cross apply t.c.nodes('Equipment') as t1(c1)

即,我正在

VIN  EquipmentDesc
---  -------------
1234 1.11.21.3
2345 2.12.22.3

我显然做错了什么,大概是交叉应用,或选择描述数据(或两者),但我不知道它是什么。看起来这很简单,但我没有看到它。

2 个答案:

答案 0 :(得分:1)

我后来意识到了答案。我只需要添加更多级别的交叉应用,以便下载到EquipmentDesc元素 - 脑损伤,编码周六晚上。

cross apply t1.c1.nodes('EquipmentDesc') as t2(c2)

使用

选择设备描述值
, t2.c2.value('.', 'varchar(80)') as EquipDesc

我不经常使用交叉应用,容易忘记当我调整一些现有代码时它真正意味着什么。对不起,如果我浪费了任何人的时间。

ADDED

最终查询(至少相关部分)

select t.c.value('VIN[1]', 'varchar(20)') as VIN
     , t2.c2.value('.', 'varchar(80)') as EquipDesc
from @xdata.nodes('//VehicleFeed/Vehicle') as t(c)
cross apply t.c.nodes('Equipment') as t1(c1)
cross apply t1.c1.nodes('EquipmentDesc') as t2(c2)

答案 1 :(得分:1)

您可以使用较短的陈述来实现相同的目标:

select t.c.value('../../VIN[1]', 'varchar(20)') as VIN
     , t.c.value('.', 'varchar(80)') as EquipDesc
from @xdata.nodes('/VehicleFeed/Vehicle/Equipment/EquipmentDesc') as t(c);