TSQL XML值返回所有记录的节点的第一个值

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)

mar*_*c_s 5

那么,要么你需要指定整个列表上方的节点<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两次