while sql server 2008中的循环引用xml.nodes

时间:2017-02-15 13:50:46

标签: sql sql-server xml

我有以下问题:

我有这两个while循环遍历xml文件的一个节点,但我看不到粘贴while循环的位置,因为它需要能够引用所述的xml节点。

DECLARE @cnt INT = 1, @temprouteor varchar(50),@temproute varchar(50);
SET @cnt = 1



WHILE @cnt < COUNT(IDC.nodes('Segment/Leg'))-1 

BEGIN
SET @temprouteor = @temprouteor + LORC.value('@CRSCode' , 'Varchar(50)' ) + '/'
SET @cnt = @cnt +1
END

WHILE @cnt = COUNT(IDC.nodes('Segment/Leg')) 
BEGIN
SET @temproute = @temprouteor + LDESC.value('@CRSCode' , 'Varchar(50)' );
END

3个节点是:

LEGC
LORC
LDESC

有没有人对如何实现这一点有任何想法?

 <Leg Ref="101" Direction="Outbound" Departure="2016-12-22T06:51:00"       Arrival="2016-12-22T07:04:00" TransportMode="TRAIN">
 <Origin UICCode="7034740" NLCCode="3474" CRSCode="TVP" Name="TIVERTON   PARKWAY" /> 
 <Destination UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <Reservation PassengerRef="77814233" AccomodationUnit="B33" /> 
 <TrainRoute Ref="101" OriginDeparture="2016-12-22T05:30:00" DestinationArrival="2016-12-22T09:21:00">
 <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="102" Direction="Outbound" Departure="2016-12-22T07:18:00" Arrival="2016-12-22T09:00:00" TransportMode="TRAIN">
 <Origin UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <Reservation PassengerRef="77814233" AccomodationUnit="D64" /> 
 <TrainRoute Ref="102" OriginDeparture="2016-12-22T05:53:00" DestinationArrival="2016-12-22T09:00:00">
 <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="103" Direction="Outbound" Departure="2016-12-22T09:15:00" Arrival="2016-12-22T09:21:00" TransportMode="TRAIN">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7030000" NLCCode="3000" CRSCode="AML" Name="ACTON MAIN LINE" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <TrainRoute Ref="103" OriginDeparture="2016-12-22T09:15:00" DestinationArrival="2016-12-22T09:40:00">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7031360" NLCCode="3136" CRSCode="GFD" Name="GREENFORD" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="601" Direction="Return" Departure="2016-12-22T14:33:00" Arrival="2016-12-22T14:42:00" TransportMode="TRAIN">
 <Origin UICCode="7030000" NLCCode="3000" CRSCode="AML" Name="ACTON MAIN LINE" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <TrainRoute Ref="601" OriginDeparture="2016-12-22T14:16:00" DestinationArrival="2016-12-22T14:42:00">
 <Origin UICCode="7031360" NLCCode="3136" CRSCode="GFD" Name="GREENFORD" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="602" Direction="Return" Departure="2016-12-22T15:06:00" Arrival="2016-12-22T17:18:00" TransportMode="TRAIN">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7034740" NLCCode="3474" CRSCode="TVP" Name="TIVERTON PARKWAY" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <Reservation PassengerRef="77814233" AccomodationUnit="B84" /> 
 <TrainRoute Ref="602" OriginDeparture="2016-12-22T15:06:00" DestinationArrival="2016-12-22T20:42:00">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7035260" NLCCode="3526" CRSCode="PNZ" Name="PENZANCE" /> 
 </TrainRoute>
 </Leg>

预期的输出是看到列车行程所有支路的连接路线。

在这种情况下: TVP / TAU / PAD / AML / PAD / TVP

1 个答案:

答案 0 :(得分:2)

<强>注意

  

WHILE @cnt&lt; COUNT(IDC.nodes('Segment / Leg')) - 1

清楚地表明,有更深的嵌套,<Leg>元素周围至少还有一个元素称为<Segment>。我不知道你的完整XML。您要么在XPath中反映这一点,要么使用.nodes(//Leg)进行深度搜索(不推荐)。

我将其减少到两个<Leg>个节点。这同样适用于更多:

DECLARE @xml XML=
N'<Leg Ref="101" Direction="Outbound" Departure="2016-12-22T06:51:00" Arrival="2016-12-22T07:04:00" TransportMode="TRAIN">
  <Origin UICCode="7034740" NLCCode="3474" CRSCode="TVP" Name="TIVERTON   PARKWAY" />
  <Destination UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" />
  <TOC Code="GW" Name="Great Western Railway" />
  <Reservation PassengerRef="77814233" AccomodationUnit="B33" />
  <TrainRoute Ref="101" OriginDeparture="2016-12-22T05:30:00" DestinationArrival="2016-12-22T09:21:00">
    <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" />
    <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" />
  </TrainRoute>
</Leg>
<Leg Ref="102" Direction="Outbound" Departure="2016-12-22T07:18:00" Arrival="2016-12-22T09:00:00" TransportMode="TRAIN">
  <Origin UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" />
  <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" />
  <TOC Code="GW" Name="Great Western Railway" />
  <Reservation PassengerRef="77814233" AccomodationUnit="D64" />
  <TrainRoute Ref="102" OriginDeparture="2016-12-22T05:53:00" DestinationArrival="2016-12-22T09:00:00">
    <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" />
    <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" />
  </TrainRoute>
</Leg>';

- 这是查询

 SELECT l.value('@Ref','int') AS Leg_Ref
       ,l.value('@Direction','nvarchar(max)') AS Leg_Direction
       ,l.value('@Departure','datetime') AS Leg_Departure
       --more attributes in <Leg>
       ,l.value('(Origin/@UICCode)[1]','int') AS Origin_UICCode
       --more attributes in `<Leg><Origin>`
       --Same approach for following elements
       ,l.value('(TrainRoute/Origin/@UICCode)[1]','int') AS TrainRoute_Origin
       --and so on...
 FROM @xml.nodes('/Leg') AS A(l)

前两个元素的结果:

101 Outbound    2016-12-22 06:51:00.000 7034740 7035800
102 Outbound    2016-12-22 07:18:00.000 7034710 7035800

更新找到您之后添加的预期输出

  

TVP / TAU / PAD / AML / PAD / TVP

这将获取有问题的节点:

 SELECT l.value('@Ref','int') AS Leg_Ref
       ,l.value('(Origin/@CRSCode)[1]','nvarchar(max)') AS Origin_CRSCode
       ,l.value('(Destination/@CRSCode)[1]','nvarchar(max)') AS Destination_CRSCode
 FROM @xml.nodes('/Leg') AS A(l)

返回样本数据

 Leg_Ref    Origin_CRSCode  Destination_CRSCode
101         TVP             TAU
102         TAU             PAD
103         PAD             AML
601         AML             PAD
602         PAD             TVP

但我不知道,这些节点是如何连接的。您可能需要递归CTE。

更新2

从你的评论中我认为你想要这个:

WITH AllLegs AS
(
     SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS PosNr
           ,l.value('@Ref','int') AS Leg_Ref
           ,l.value('(Origin/@CRSCode)[1]','nvarchar(max)') AS Orig
           ,l.value('(Destination/@CRSCode)[1]','nvarchar(max)') AS Dest
     FROM @xml.nodes('/Leg') AS A(l)
)
SELECT Orig + '/' + Dest
    + (
        SELECT '/' + Dest FROM AllLegs WHERE PosNr>1 ORDER BY PosNr FOR XML PATH('')
      )
 FROM AllLegs WHERE PosNr=1

结果

 TVP/TAU/PAD/AML/PAD/TVP