简体   繁体   中英

XML tag parsing into a columns using XQuery

I have below XML structure

<customMessages id="c928E0908E3A2482B91200B5ABDE4262B">
    <Referrals id="R05D2A8F94F5B44138E6CF43DA06AFB42">
        <message refObject="pB1F92D8F1F3442629052904FB4751602" flag="refer" 
                 category="(message)" controllingId="ReferralRules.IsBindableAssistant"     
                 messageName="ReferralRules.IsBindableAssistantMsg65"     
                 id="m79DD647217A54FC2AE7D129B095C29EC">Snow removal is performed for others &lt; 25,000</message>
        <message refObject="pB1F92D8F1F3442629052904FB4751602" flag="refer" 
                 category="(message)" controllingId="ReferralRules.IsBindableAssistant" 
                 messageName="ReferralRules.IsBindableAssistantMsg166" 
                 id="mABF6DE099DA04517A57D822B3DB0344D">Foreign Revenue</message>
        <message refObject="pB1F92D8F1F3442629052904FB4751602" flag="refer" 
                 category="(message)" controllingId="ReferralRules.IsBindableAssistant" 
                 messageName="ReferralRules.IsBindableAssistantMsg167" 
                 id="mEB086005E0124CF59EF3F8DBCC25C99A">US Revenue</message>
    </Referrals>
</customMessages>

I want an output as below

CustomMessageId  Message
id1               message1
id1               message2
id1               message3 .. n

Please note that message has multiple values

I am using below query

  Select 
      x.r.value('(@id)[1]', 'varchar(500)') as CustomMessageId,
      Case 
         When y.r.value('(message)[1]', 'varchar(500)') = '' 
            Then NULL 
         Else y.r.value('(message)[1]','varchar(500)') 
      End as message
  from
      (SELECT  
           Cast(XMLData as XML) XMLData
       FROM
           Table A) s
  CROSS apply 
      s.XMLData.nodes('session/customMessages') as x(r)
  CROSS apply 
      s.XMLData.nodes('session/customMessages/Referrals/message') as y(r)

However, I am getting only the first instance of message and not all the messages. Can anyone help?

Did you simplify your query some how or real data are different? that query "as is" must return:

CustomMessageId                                 Message
c928E0908E3A2482B91200B5ABDE4262B               NULL
c928E0908E3A2482B91200B5ABDE4262B               NULL
c928E0908E3A2482B91200B5ABDE4262B               NULL

I tested it and did not get "only first instance" I got NULL for all three.

Problem: XPath in nodes for y(r) and in yrvalue quite not correct.

you make a set of nodes from session/customMessages/Referrals/message and then try to get <message> node value again from <message> . It is not there and result is NULL.

to fix it you need to do either change line

s.XMLData.nodes('session/customMessages/Referrals/message') as y(r)

to

s.XMLData.nodes('session/customMessages/Referrals') as y(r)

or in all yrvalue functions use text() node as

y.r.value('(text())[1]', 'varchar(500)')

That is preferable from XPath point of view, but not critical.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM