我有一个xml值。我试图解析它,但是结果为空 我的Xml
<DataPDU xmlns="urn:cma:stp:xsd:stp.1.0">
<Body>
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.01">
<Fr>
<FIId>
<FinInstnId>
<ClrSysMmbId>
<MmbId>4588745121</MmbId>
</ClrSysMmbId>
</FinInstnId>
</FIId>
</Fr>
<To>
<FIId>
<FinInstnId>
<ClrSysMmbId>
<MmbId>3501548751245701797</MmbId>
</ClrSysMmbId>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr>Pac.Convert</BizMsgIdr>
<MsgDefIdr>Pac.Convert.2019</MsgDefIdr>
<BizSvc>Line</BizSvc>
<CreDt>2019-06-07T17:06:35.38Z</CreDt>
</AppHdr>
</Body>
</DataPDU>
我的查询解析工作很好,没有属性,但属性返回null 我的查询:
Select
x.XmlCol.value(N'(./Fr/FIId/FinInstnId/ClrSysMmbId/MmbId)[1]','nvarchar(200)') as FR_MmbId, --Идентификация устанавливается со стороны отправителя
x.XmlCol.value(N'(./To/FIId/FinInstnId/ClrSysMmbId/MmbId)[1]','nvarchar(200)') as TO_MmbId,
x.XmlCol.value(N'(./BizMsgIdr)[1]','nvarchar(200)') as BizMsgIdr
from @Xml.nodes(N'/DataPDU/Body/AppHdr') x(XmlCol)
答案 0 :(得分:2)
涉及两个名称空间。两者都没有前缀,因此显示为默认名称空间。所有值都位于内部默认名称空间中。因此,为简单起见,我建议对外部使用前缀。这使您可以处理所有不带前缀的内部元素:
;WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:head.001.001.01'
,'urn:cma:stp:xsd:stp.1.0' AS ns)
SELECT AppHdr.value(N'(Fr/FIId/FinInstnId/ClrSysMmbId/MmbId/text())[1]','nvarchar(200)') as FR_MmbId
,AppHdr.value(N'(To/FIId/FinInstnId/ClrSysMmbId/MmbId/text())[1]','nvarchar(200)') as TO_MmbId
,AppHdr.value(N'(BizMsgIdr/text())[1]','nvarchar(200)') as BizMsgIdr
FROM @Xml.nodes(N'/ns:DataPDU/ns:Body/AppHdr') A(AppHdr);
此外,您可以省略外部名称空间并使用通配符:
;WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:head.001.001.01')
SELECT AppHdr.value(N'(Fr/FIId/FinInstnId/ClrSysMmbId/MmbId/text())[1]','nvarchar(200)') as FR_MmbId
,AppHdr.value(N'(To/FIId/FinInstnId/ClrSysMmbId/MmbId/text())[1]','nvarchar(200)') as TO_MmbId
,AppHdr.value(N'(BizMsgIdr/text())[1]','nvarchar(200)') as BizMsgIdr
FROM @Xml.nodes(N'/*:DataPDU/*:Body/AppHdr') A(AppHdr);
在开头加上双斜杠的深度搜索也可以工作(只要XML中只有一个<AppHdr>
元素即可。
;WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:head.001.001.01')
SELECT AppHdr.value(N'(Fr/FIId/FinInstnId/ClrSysMmbId/MmbId/text())[1]','nvarchar(200)') as FR_MmbId
,AppHdr.value(N'(To/FIId/FinInstnId/ClrSysMmbId/MmbId/text())[1]','nvarchar(200)') as TO_MmbId
,AppHdr.value(N'(BizMsgIdr/text())[1]','nvarchar(200)') as BizMsgIdr
FROM @Xml.nodes(N'//AppHdr') A(AppHdr);
只是为了好玩:这也可行(对于给定的XML,不推荐):
SELECT @xml.value(N'(//*:Fr//*:MmbId/text())[1]','nvarchar(200)') as FR_MmbId
,@xml.value(N'(//*:To//*:MmbId/text())[1]','nvarchar(200)') as TO_MmbId
,@xml.value(N'(//*:BizMsgIdr/text())[1]','nvarchar(200)') as BizMsgIdr
即使这样也可以(对于给定的XML,不推荐):-)
SELECT @xml.value(N'(//*:Fr)[1]','nvarchar(200)') as FR_MmbId
,@xml.value(N'(//*:To)[1]','nvarchar(200)') as TO_MmbId
,@xml.value(N'(//*:BizMsgIdr)[1]','nvarchar(200)') as BizMsgIdr
一般建议是:尽可能具体。这有助于避免名称冲突,并具有更好的性能。
答案 1 :(得分:1)
您需要在不同节点中处理XMLNAMESPACES(xmlns),以获得所需的输出。尝试如下-
;WITH XMLNAMESPACES(
'urn:cma:stp:xsd:stp.1.0' AS N1,
'urn:iso:std:iso:20022:tech:xsd:head.001.001.01' AS N2,
DEFAULT 'urn:cma:stp:xsd:stp.1.0'
)
Select
x.XmlCol.value(N'(./N2:Fr/N2:FIId/N2:FinInstnId/N2:ClrSysMmbId/N2:MmbId)[1]','nvarchar(200)') as FR_MmbId, --Идентификация устанавливается со стороны отправителя
x.XmlCol.value(N'(./N2:To/N2:FIId/N2:FinInstnId/N2:ClrSysMmbId/N2:MmbId)[1]','nvarchar(200)') as TO_MmbId,
x.XmlCol.value(N'(./N2:BizMsgIdr)[1]','nvarchar(200)') as BizMsgIdr
from @Xml.nodes(N'/N1:DataPDU/Body/N2:AppHdr') x(XmlCol)