簡體   English   中英

使用XQuery解析表列中的XML

[英]Using XQuery to Parse XML in a table column

我正在SSMS 2008中運行以下命令,以嘗試從節點中獲取數據,以便於搜索和限制值。 這是供應商發送給我們的XML,我們經常需要搜索以查找已發送的消息,目前,它尚未進行優化以在表級別拆分數據。 (目前無法執行此操作)。 MessageStringXML是XML數據類型的字段。 以下查詢沒有任何結果。

;WITH XMLNAMESPACES(DEFAULT 'http://www.opentravel.org/OTA/2003/05')
Select Case When MessageStringXML.value('(/OTA_HotelAvailNotifRQ/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelAvailNotifRQ/@EchoToken)[1]','varchar(255)')
            When MessageStringXML.value('(/OTA_HotelAvailNotifRS/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelAvailNotifRS/@EchoToken)[1]','varchar(255)')
            When MessageStringXML.value('(/OTA_HotelRateAmountNotifRQ/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelRateAmountNotifRQ/@EchoToken)[1]','varchar(255)')
            When MessageStringXML.value('(/OTA_HotelRateAmountNotifRS/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelRateAmountNotifRS/@EchoToken)[1]','varchar(255)')
       End as EchoToken
      ,Toddler.value('@InvCode','varchar(255)') as RoomTypeCode
      ,Toddler.value('@RatePlanCode','varchar(255)') as RateCode
      ,Infant.value('@Status','varchar(255)') as 'Status'
From #Gamma
    Cross Apply MessageStringXML.nodes('/OTA_HotelAvailNotifRQ/AvailStatusMessages/AvailStatusMessage') AS N(Child)
    Cross Apply Child.nodes('/StatusApplicationControl') AS O(Toddler)
    Cross Apply Child.nodes('/RestrictionStatus') AS P(Infant)

以下是我嘗試解析的XML消息的示例:

<OTA_HotelAvailNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" EchoToken="123456789" TimeStamp="2013-08-13T10:56:25.32-05:00" Target="Production" Version="1.001" PrimaryLangID="en-us">
  <POS>
    <Source>
      <RequestorID Type="18" ID="AAAAAA" />
    </Source>
  </POS>
  <AvailStatusMessages ChainCode="BB" BrandCode="CC" HotelCode="12345">
    <AvailStatusMessage>
      <StatusApplicationControl Start="2014-05-11" End="2014-07-09" InvCodeApplication="InvCode" InvCode="DDD" RatePlanCodeType="RatePlanCode" RatePlanCode="EEE" RateTier="8" IsRoom="1" Override="1" />
      <RestrictionStatus Restriction="Master" Status="Open" />
    </AvailStatusMessage>
    <AvailStatusMessage>
      <StatusApplicationControl Start="2014-05-11" End="2014-07-09" InvCodeApplication="InvCode" InvCode="FFF" RatePlanCodeType="RatePlanCode" RatePlanCode="GGG" RateTier="9" IsRoom="1" Override="1" />
      <RestrictionStatus Restriction="Master" Status="Close" />
    </AvailStatusMessage>
  </AvailStatusMessages>
</OTA_HotelAvailNotifRQ>

編輯:

效果非常好!!! 謝謝! 我還沒有找到很多很好的文檔資料來源,所以我對此表示贊賞。 如果我嘗試進一步研究其他XML,

<OTA_HotelAvailNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" EchoToken="34496481-1" PrimaryLangID="en-us" Target="Production" TimeStamp="2013-09-06T05:50:37.01+00:00" Version="1.002">
  <POS>
    <Source>
      <RequestorID ID="R_GoldenTulip" Type="18" />
    </Source>
  </POS>
  <AvailStatusMessages BrandCode="GT" ChainCode="GT" HotelCode="040510">
    <AvailStatusMessage>
      <StatusApplicationControl End="2013-10-06" Fri="true" InvCode="ROH" InvCodeApplication="InvCode" Mon="true" RatePlanCode="EXPED1" RatePlanCodeType="RatePlanCode" Sat="true" Start="2013-10-04" Sun="true" Thur="true" Tue="true" Weds="true" />
      <RestrictionStatus Restriction="Master" Status="Open" />
    </AvailStatusMessage>
    <AvailStatusMessage>
      <StatusApplicationControl End="2013-10-06" Fri="true" InvCode="ROH" InvCodeApplication="InvCode" Mon="true" RatePlanCode="EXPED1" RatePlanCodeType="RatePlanCode" Sat="true" Start="2013-10-04" Sun="true" Thur="true" Tue="true" Weds="true" />
      <LengthsOfStay ArrivalDateBased="true" FixedPatternLength="1">
        <LengthOfStay MinMaxMessageType="FullPatternLOS" Time="1" TimeUnit="Day" />
      </LengthsOfStay>
    </AvailStatusMessage>
    <AvailStatusMessage>
      <StatusApplicationControl End="2013-10-06" Fri="true" InvCode="ROH" InvCodeApplication="InvCode" Mon="true" RatePlanCode="EXPED1" RatePlanCodeType="RatePlanCode" Sat="true" Start="2013-10-04" Sun="true" Thur="true" Tue="true" Weds="true" />
      <LengthsOfStay ArrivalDateBased="false" FixedPatternLength="1">
        <LengthOfStay MinMaxMessageType="FullPatternLOS" Time="1" TimeUnit="Day" />
      </LengthsOfStay>
    </AvailStatusMessage>
  </AvailStatusMessages>
</OTA_HotelAvailNotifRQ>

我現在想打“ LengthsOfStay”節點,我的SQL在下面。 我認為這可能與並非所有具有“ LengthsOfStay”節點的郵件有關

;WITH XMLNAMESPACES(DEFAULT 'http://www.opentravel.org/OTA/2003/05')

Select 
[MessageBodyID],
Case When MessageStringXML.value('(/OTA_HotelAvailNotifRQ/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelAvailNotifRQ/@EchoToken)[1]','varchar(255)')
            When MessageStringXML.value('(/OTA_HotelAvailNotifRS/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelAvailNotifRS/@EchoToken)[1]','varchar(255)')
            When MessageStringXML.value('(/OTA_HotelRateAmountNotifRQ/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelRateAmountNotifRQ/@EchoToken)[1]','varchar(255)')
            When MessageStringXML.value('(/OTA_HotelRateAmountNotifRS/@EchoToken)[1]','varchar(255)') IS Not Null Then MessageStringXML.value('(/OTA_HotelRateAmountNotifRS/@EchoToken)[1]','varchar(255)')
       End as EchoToken
      ,Toddler.value('@InvCode','varchar(255)') as RoomTypeCode
      ,Toddler.value('@Start','varchar(255)') as FromDate
      ,Toddler.value('@End','varchar(255)') as ToDate
      ,Toddler.value('@RatePlanCode','varchar(255)') as RateCode
      ,Infant.value('@Status','varchar(255)') as 'Status'
      ,Fetus.value('@ArrivalDateBased','varchar(255)') as 'FPLOS'

From #Alpha
    Cross Apply MessageStringXML.nodes('OTA_HotelAvailNotifRQ/AvailStatusMessages') AS N(Tween)
    Cross Apply Tween.nodes('AvailStatusMessage') AS Q(Child)
    Cross Apply Child.nodes('StatusApplicationControl') AS O(Toddler)
    Cross Apply Child.nodes('RestrictionStatus') AS P(Infant)
    Cross Apply Child.nodes('LengthsOfStay') AS R(Fetus)
    --Cross Apply Fetus.nodes('Lengthofstay') AS S(Embryo)

改變這個

Cross Apply Child.nodes('/StatusApplicationControl') AS O(Toddler)
Cross Apply Child.nodes('/RestrictionStatus') AS P(Infant)

對此

Cross Apply Child.nodes('StatusApplicationControl') AS O(Toddler)
Cross Apply Child.nodes('RestrictionStatus') AS P(Infant)

或確實

Cross Apply Child.nodes('./StatusApplicationControl') AS O(Toddler)
Cross Apply Child.nodes('./RestrictionStatus') AS P(Infant)

你應該得到行。 原始的首字母/使它返回文檔根目錄以查找您命名的節點。 通過使用./或不使用前綴,您說的是“從當前上下文搜索”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM