Reputation: 187
I would like using tsql get value of ChargeType from xml file. I wrote script but, it always returns value 'Principal' for both xml records. I can't understand what is wrong and how to fix problem? Script should return values:
ChargeType
Principal
Taxed
Current result
ChargeType
Principal
Principal
Source code
DECLARE @xml XML = '<ListFinancialEventsResponse xmlns="http://www.test.com">
<ListFinancialEventsResult>
<FinancialEvents>
<ShipmentEventList>
<ShipmentEvent>
<ShipmentItemList>
<ShipmentItem>
<ItemChargeList>
<ChargeComponent>
<ChargeType>Principal</ChargeType>
<ChargeAmount>
<CurrencyAmount>20.4</CurrencyAmount>
<CurrencyCode>RUR</CurrencyCode>
</ChargeAmount>
</ChargeComponent>
<ChargeComponent>
<ChargeType>Taxed</ChargeType>
<ChargeAmount>
<CurrencyAmount>1.23</CurrencyAmount>
<CurrencyCode>GEL</CurrencyCode>
</ChargeAmount>
</ChargeComponent>
</ItemChargeList>
</ShipmentItem>
</ShipmentItemList>
</ShipmentEvent>
</ShipmentEventList>
</FinancialEvents>
</ListFinancialEventsResult>
</ListFinancialEventsResponse>';
;WITH XMLNAMESPACES('http://www.test.com' as ns)
select
lfer.c.value('(//ns:ChargeType)[1]', 'nvarchar(50)') AS ChargeType
from @xml.nodes('//ns:ListFinancialEventsResponse//ns:ListFinancialEventsResult//ns:ShipmentItemList//ns:ShipmentItem//ns:ItemChargeList//ns:ChargeComponent') lfer(c)
Upvotes: 2
Views: 440
Reputation: 754538
Well, either you need to specify the whole list of nodes above <ChargeType>
in your XPath, using single dashes (right now, you're leaving out a few)
@xml.nodes('/ns:ListFinancialEventsResponse/ns:ListFinancialEventsResult/ns:FinancialEvents/ns:ShipmentEventList .......
or then you need to use this XPath to get just the <ChargeComponent>
nodes and grab the <ChargeType>
from those.
Try this T-SQL:
;WITH XMLNAMESPACES('http://www.test.com' as ns)
SELECT
-- do *NOT* use double dashes here!
lfer.c.value('(ns:ChargeType)[1]', 'nvarchar(50)') AS ChargeType
FROM
-- just grab *all* <ChargeComponent> nodes anywhere in the XML
@xml.nodes('//ns:ChargeComponent') lfer(c)
Your existing code here:
lfer.c.value('(//ns:ChargeType)[1]'
means: give me all the <ChargeType>
nodes (because of the leading //
) and then take the first of all of those nodes - that's why you're getting the node with the Principal
twice
Upvotes: 5