SELECT FROM XML MULTIPLE ELEMENTS SQL

时间:2017-11-21 10:56:31

标签: sql sql-server

我希望使用SQL选择返回XML。当我指定元素的索引时,我没有从XML中选择的问题。这是有问题的XML。

<root httpStatusCode="200">
    <messages />
    <succesfulResponses>
        <item position="0">
            <response dln="TESTDLN" ServiceVersion="1" hubServiceVersion="1.0.0.0" ProcessingDate="2017-11-20T10:42:20.579Z" hubProcessingDate="2017-11-20T10:41:16.5415151Z" httpStatusCode="200">
                <licence status="FC" validFrom="2017-03-18" validTo="2024-10-31" directiveIndicator="4">
                    <entitlements>
                        <item code="A" validFrom="2006-04-07" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="AM" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions>
                                <item type="122" info="null" />
                            </restrictions>
                        </item>
                        <item code="B" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions />
                        </item>
                        <item code="BE" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="F" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions />
                        </item>
                        <item code="G" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="H" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="K" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions />
                        </item>
                        <item code="Q" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions>
                                <item type="122" info="null" />
                            </restrictions>
                        </item>
                    </entitlements>
                    <endorsements />
                </licence>
                <messages />
            </response>
        </item>
    </succesfulResponses>
    <errorResponses />
</root>

到目前为止我写的SQL如下:

select
Rec.value('(@dln)[1]','char(50)'),
Rec.value('(licence/@status)[1]','char(2)'),
pd.value('(entitlements/item/@code)[1]','char(2)')
FROM @xmlData.nodes('//root/succesfulResponses/item/response') as x(Rec)
cross apply @xmlData.nodes('//root/succesfulResponses/item/response/licence') as i(pd)

这显然返回了&#39; A&#39;的第一行代码,但是可以有多个权利&#39;而且我也不知道有多少可能有3个可能有9个。

我认为Cross Apply会起作用,但我似乎无法做到这一点。

任何想法/帮助。

2 个答案:

答案 0 :(得分:2)

试试这个 - 在CROSS APPLY之后展开XPath以包含entitlements/item部分:

select
    Rec.value('(@dln)[1]','char(50)'),
    Rec.value('(licence/@status)[1]','char(2)'),
    pd.value('@code', 'char(2)')
FROM
     @xmlData.nodes('//root/succesfulResponses/item/response') as x(Rec)
cross apply 
    @xmlData.nodes('//root/succesfulResponses/item/response/licence/entitlements/item') as i(pd)

返回:

enter image description here

答案 1 :(得分:0)

OPENXML

的变体
DECLARE @idoc int, @doc varchar(MAX)

SET @doc='<root httpStatusCode="200">
    <messages />
    <succesfulResponses>
        <item position="0">
            <response dln="TESTDLN" ServiceVersion="1" hubServiceVersion="1.0.0.0" ProcessingDate="2017-11-20T10:42:20.579Z" hubProcessingDate="2017-11-20T10:41:16.5415151Z" httpStatusCode="200">
                <licence status="FC" validFrom="2017-03-18" validTo="2024-10-31" directiveIndicator="4">
                    <entitlements>
                        <item code="A" validFrom="2006-04-07" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="AM" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions>
                                <item type="122" info="null" />
                            </restrictions>
                        </item>
                        <item code="B" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions />
                        </item>
                        <item code="BE" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="F" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions />
                        </item>
                        <item code="G" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="H" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
                            <restrictions />
                        </item>
                        <item code="K" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions />
                        </item>
                        <item code="Q" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
                            <restrictions>
                                <item type="122" info="null" />
                            </restrictions>
                        </item>
                    </entitlements>
                    <endorsements />
                </licence>
                <messages />
            </response>
        </item>
    </succesfulResponses>
    <errorResponses />
</root>'


EXEC sp_xml_preparedocument @idoc OUTPUT, @doc;

SELECT *  
FROM OPENXML(@idoc,'/root/succesfulResponses/item/response/licence/entitlements/item',2)   
  WITH (
          status        varchar(10)         '../../@status',
          code          varchar(10)         './@code',
          validFrom     date                './@validFrom'
        );

EXEC sp_xml_removedocument @idoc;
GO