Yur*_*iev 2 xml t-sql sql-server nodes
我想使用tsql从xml文件获取ChargeType的值。我写了脚本,但是它总是为两个xml记录返回值“ Principal”。我不明白哪里出了问题以及如何解决问题?脚本应返回值:
ChargeType
Principal
Taxed
Run Code Online (Sandbox Code Playgroud)
当前结果
ChargeType
Principal
Principal
Run Code Online (Sandbox Code Playgroud)
源代码
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)
Run Code Online (Sandbox Code Playgroud)
那么,要么你需要指定整个列表上方的节点<ChargeType>在你的XPath,使用单一的破折号(现在,你离开了几个)
@xml.nodes('/ns:ListFinancialEventsResponse/ns:ListFinancialEventsResult/ns:FinancialEvents/ns:ShipmentEventList .......
Run Code Online (Sandbox Code Playgroud)
否则,您需要使用此XPath来获取<ChargeComponent>节点并从中获取节点<ChargeType>。
试试这个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)
Run Code Online (Sandbox Code Playgroud)
您现有的代码在这里:
lfer.c.value('(//ns:ChargeType)[1]'
Run Code Online (Sandbox Code Playgroud)
方法:给我所有的<ChargeType>节点(因为领先//),然后采取第一所有这些节点的-这就是为什么你得到节点与Principal两次