当某些节点丢失时获取XML节点属性值

时间:2014-04-14 07:10:08

标签: sql sql-server sql-server-2008

使用以下查询我正在从XML中检索值。

 DECLARE @XMLDoc2 XML,
 @PKDevice int,
 @PKMessageType INT

 SET @XMLDoc2=
 '<MT10 v="2.0.0">
  <L>
    <PKL>119</PKL>   
    <DID>123</DID>
    <DDT>2014-04-09T17:59:55</DDT>
    <D>
      <PKD>1007</PKD>
      <SDT>09-Apr-2014 17:55:57</SDT>
      <SIG>2</SIG>
      <SNR>group</SNR>     
      <RCD>null</RCD>
      <RDL>0</RDL>
      <DL>
        <PKDD PCD="2" RCS="0" RSS="1">3142</PKDD>
        <PKDD PCD="24" RCS="0" RSS="1">3143</PKDD>
      </DL>
    </D>
  </L>
</MT10>
'

    SELECT 
           L.N.value('(PKL/text())[1]', 'int') AS PKL,
           L.N.value('(DID/text())[1]', 'int') AS DID,
           L.N.value('(DDT/text())[1]', 'datetime') AS DDT,
           P.N.value('text()[1]', 'int') AS PKD,
           SI.N.value('text()[1]', 'int') AS SIG,
           SN.N.value('text()[1]', 'varchar(max)') AS SNR,
           RC.N.value('text()[1]', 'varchar(max)') AS RCD,
           RD.N.value('text()[1]', 'int') AS RDL,
           PKD.N.value('text()[1]', 'int') AS PKDD,
           PKD.N.value('@PCD', 'int') AS PCD,
           PKD.N.value('@RCS', 'int') AS RCS,
           PKD.N.value('@RSS', 'int') AS RSS

    FROM  
           @xmldoc2.nodes('/MT10/L') AS L(N)
                      CROSS APPLY 
           L.N.nodes('D/PKD') AS P(N)
                      CROSS APPLY 
           L.N.nodes('D/SIG') AS SI(N)
                      CROSS APPLY 
           L.N.nodes('D/SNR') AS SN(N)
                      CROSS APPLY 
           L.N.nodes('D/RCD') AS RC(N)
                      CROSS APPLY 
           L.N.nodes('D/RDL') AS RD(N)
                       CROSS APPLY
           L.N.nodes('D/DL/PKDD') AS PKD(N)

问题在于,对于某些XML,<DL></DL>标记不会出现,而对于某些标记,<DL></DL>标记将在那里。我需要在单个查询中处理这两个条件。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

我认为这会有所帮助......对于那些有时会出现这种情况的标签,使用OUTER APPLY ......在这种情况下,dl标签

SELECT 
           L.N.value('(PKL/text())[1]', 'int') AS PKL,
           L.N.value('(DID/text())[1]', 'int') AS DID,
           L.N.value('(DDT/text())[1]', 'datetime') AS DDT,
           P.N.value('text()[1]', 'int') AS PKD,
           SI.N.value('text()[1]', 'int') AS SIG,
           SN.N.value('text()[1]', 'varchar(max)') AS SNR,
           RC.N.value('text()[1]', 'varchar(max)') AS RCD,
           RD.N.value('text()[1]', 'int') AS RDL,
           PKD.N.value('text()[1]', 'int') AS PKDD,
           PKD.N.value('@PCD', 'int') AS PCD,
           PKD.N.value('@RCS', 'int') AS RCS,
           PKD.N.value('@RSS', 'int') AS RSS

    FROM  
           @xmldoc2.nodes('/MT10/L') AS L(N)
                      CROSS APPLY 
           L.N.nodes('D/PKD') AS P(N)
                      CROSS APPLY 
           L.N.nodes('D/SIG') AS SI(N)
                      CROSS APPLY 
           L.N.nodes('D/SNR') AS SN(N)
                      CROSS APPLY 
           L.N.nodes('D/RCD') AS RC(N)
                      CROSS APPLY 
           L.N.nodes('D/RDL') AS RD(N)
                       OUTER APPLY
           L.N.nodes('D/DL/PKDD') AS PKD(N)