我希望使用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会起作用,但我似乎无法做到这一点。
任何想法/帮助。
答案 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)
返回:
答案 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