OPENXML 导入 xml 到 ms sql - 命名空间
OPENXML import xml to ms sql - namespace
我使用这个网站很长时间了,很多次它帮助我解决了各种问题。
这次我卡住了。我尝试将一个复杂的 xml 导入到 ms-sql table 中,如下所示。
<?xml version='1.0' encoding='UTF-8'?>
<S2SCTScf:SCTScfBlkCredTrf xmlns="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:S2SCTScf="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd">
<S2SCTScf:SndgInst>XXXXXXXX</S2SCTScf:SndgInst>
<S2SCTScf:RcvgInst>YYYYYYYY</S2SCTScf:RcvgInst>
<S2SCTScf:SrvcId>SCT</S2SCTScf:SrvcId>
<S2SCTScf:TstCode>P</S2SCTScf:TstCode>
<S2SCTScf:FType>SCF</S2SCTScf:FType>
<S2SCTScf:FileRef>AAAAAAAAAAAAAAAAAAA</S2SCTScf:FileRef>
<S2SCTScf:RoutingInd>IND</S2SCTScf:RoutingInd>
<S2SCTScf:FileBusDt>2016-11-01</S2SCTScf:FileBusDt>
<S2SCTScf:FileCycleNo>01</S2SCTScf:FileCycleNo>
<S2SCTScf:FIToFICstmrCdtTrf xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02">
<GrpHdr>
<MsgId>111111111111111111</MsgId>
<CreDtTm>2016-11-01T15:45:11.0Z</CreDtTm>
<NbOfTxs>11</NbOfTxs>
<TtlIntrBkSttlmAmt Ccy="EUR">111111</TtlIntrBkSttlmAmt>
<IntrBkSttlmDt>2016-11-01</IntrBkSttlmDt>
<SttlmInf>
<SttlmMtd>CLRG</SttlmMtd>
<ClrSys>
<Prtry>ST2</Prtry>
</ClrSys>
</SttlmInf>
<InstgAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstgAgt>
<InstdAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstdAgt>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>MXXXXXX XXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>XXXXXXXXXXXXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
</S2SCTScf:FIToFICstmrCdtTrf>
</S2SCTScf:SCTScfBlkCredTrf>
我尝试了 OPENXML 和 XQuery 函数,但我在声明和使用命名空间(或命名空间uri)时遇到了一些问题。我不熟悉如此复杂的 xml 和 namespaceuri。我需要一个想法来获取 table 下方的数据。我成功地使用了更简单的 xml,即使只有一个命名空间。我已经手动删除了前 11 行,select 波纹管工作得很好......
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @XML = XMLData FROM XMLwithOpenXML where id=6 --this is the xml without first 11 lines
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
SELECT * FROM OPENXML(@hDoc, 'FIToFICstmrCdtTrf/CdtTrfTxInf')
WITH
(
CCY [varchar](100) 'IntrBkSttlmAmt/@Ccy',
IntrBkSttlmAmt [varchar](100) 'IntrBkSttlmAmt',
TxId [varchar](100) 'PmtId/TxId',
EndToEndId [varchar](100) 'PmtId/EndToEndId',
ChrgBr [varchar](100) 'ChrgBr'
--etc
)
EXEC sp_xml_removedocument @hDoc
GO
先说几点
FROM OPENXML
已过时,不应再使用(极少数例外退出)
- 您的 XML 在此处包含显式编码
<?xml version=''1.0'' encoding=''UTF-8''?>
。这会迫使您走 VARCHAR
路径,这在与非纯拉丁字符的连接中是危险的。最好将其替换为 utf-16
并转到 NVARCHAR
路径。在这种情况下,您 必须 在 XML 文字前设置一个 "N"。
- 您必须处理相当复杂的命名空间...难以阅读...如果您可以确定没有重复的名称,您可以放弃命名空间声明并放置一个
*:
在每个元素的前面。
- 什么增加了一些额外的努力:你的内部
S2SCTScf:FIToFICstmrCdtTrf
定义了一个新的默认名称空间。我用 innerDeflt
. 作为别名
这是变量声明
DECLARE @xml XML=
'<?xml version=''1.0'' encoding=''UTF-8''?>
<S2SCTScf:SCTScfBlkCredTrf xmlns="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:S2SCTScf="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd">
<S2SCTScf:SndgInst>XXXXXXXX</S2SCTScf:SndgInst>
<S2SCTScf:RcvgInst>YYYYYYYY</S2SCTScf:RcvgInst>
<S2SCTScf:SrvcId>SCT</S2SCTScf:SrvcId>
<S2SCTScf:TstCode>P</S2SCTScf:TstCode>
<S2SCTScf:FType>SCF</S2SCTScf:FType>
<S2SCTScf:FileRef>AAAAAAAAAAAAAAAAAAA</S2SCTScf:FileRef>
<S2SCTScf:RoutingInd>IND</S2SCTScf:RoutingInd>
<S2SCTScf:FileBusDt>2016-11-01</S2SCTScf:FileBusDt>
<S2SCTScf:FileCycleNo>01</S2SCTScf:FileCycleNo>
<S2SCTScf:FIToFICstmrCdtTrf xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02">
<GrpHdr>
<MsgId>111111111111111111</MsgId>
<CreDtTm>2016-11-01T15:45:11.0Z</CreDtTm>
<NbOfTxs>11</NbOfTxs>
<TtlIntrBkSttlmAmt Ccy="EUR">111111</TtlIntrBkSttlmAmt>
<IntrBkSttlmDt>2016-11-01</IntrBkSttlmDt>
<SttlmInf>
<SttlmMtd>CLRG</SttlmMtd>
<ClrSys>
<Prtry>ST2</Prtry>
</ClrSys>
</SttlmInf>
<InstgAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstgAgt>
<InstdAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstdAgt>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>MXXXXXX XXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>XXXXXXXXXXXXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
</S2SCTScf:FIToFICstmrCdtTrf>
</S2SCTScf:SCTScfBlkCredTrf>';
这是查询:首先声明所有命名空间。您的节点是纯结构化的 1:1,因此只需在构成 XPath
的元素名称后添加元素名称即可读取它们。只有 <CdtTrfTxInf>
出现两次,需要 1:n-approach
和 APPLY
和 .nodes()
.
在我的示例中,您会为 XML 中隐藏的任何类型的数据获得一个模板。剩下的就看你了。
WITH XMLNAMESPACES(DEFAULT 'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf'
,'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf' as S2SCTScf
,'http://www.w3.org/2001/XMLSchema-instance' AS xsi
,'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd' AS schemaLocation
,'urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02' AS innerDeflt)
SELECT rt.value(N'(S2SCTScf:SndgInst)[1]','nvarchar(max)') AS SndgInst
,rt.value(N'(S2SCTScf:RcvgInst)[1]','nvarchar(max)') AS RcvgInst
--more like this
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:MsgId)[1]','nvarchar(max)') AS MsgId
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:CreDtTm)[1]','datetime') AS CreDtTm
--more like this
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:TtlIntrBkSttlmAmt/@Ccy)[1]','nvarchar(max)') AS TtlIntrBkSttlmAmt_Ccy
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:TtlIntrBkSttlmAmt)[1]','int') AS TtlIntrBkSttlmAmt
--all nodes are 1:1, just "more of the same"
--But CdtTrfTxInf is there twice, therefore the call to OUTER APPLY rt.nodes()
,cti.value(N'(innerDeflt:PmtId/innerDeflt:EndToEndId)[1]','nvarchar(max)') AS EndToEndId
--all the rest is following the same schema...
FROM @xml.nodes(N'S2SCTScf:SCTScfBlkCredTrf') AS A(rt) --root
OUTER APPLY rt.nodes(N'S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:CdtTrfTxInf') AS B(cti) --CdtTrfTxInf
部分结果(字幕移位...)
SndgInst RcvgInst MsgId CreDtTm TtlIntrBkSttlmAmt_Ccy TtlIntrBkSttlmAmt EndToEndId
XXXXXXXX YYYYYYYY 111111111111111111 2016-11-01 15:45:11.000 EUR 111111 NOTPROVIDED
XXXXXXXX YYYYYYYY 111111111111111111 2016-11-01 15:45:11.000 EUR 111111 NOTPROVIDED
我使用这个网站很长时间了,很多次它帮助我解决了各种问题。 这次我卡住了。我尝试将一个复杂的 xml 导入到 ms-sql table 中,如下所示。
<?xml version='1.0' encoding='UTF-8'?>
<S2SCTScf:SCTScfBlkCredTrf xmlns="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:S2SCTScf="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd">
<S2SCTScf:SndgInst>XXXXXXXX</S2SCTScf:SndgInst>
<S2SCTScf:RcvgInst>YYYYYYYY</S2SCTScf:RcvgInst>
<S2SCTScf:SrvcId>SCT</S2SCTScf:SrvcId>
<S2SCTScf:TstCode>P</S2SCTScf:TstCode>
<S2SCTScf:FType>SCF</S2SCTScf:FType>
<S2SCTScf:FileRef>AAAAAAAAAAAAAAAAAAA</S2SCTScf:FileRef>
<S2SCTScf:RoutingInd>IND</S2SCTScf:RoutingInd>
<S2SCTScf:FileBusDt>2016-11-01</S2SCTScf:FileBusDt>
<S2SCTScf:FileCycleNo>01</S2SCTScf:FileCycleNo>
<S2SCTScf:FIToFICstmrCdtTrf xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02">
<GrpHdr>
<MsgId>111111111111111111</MsgId>
<CreDtTm>2016-11-01T15:45:11.0Z</CreDtTm>
<NbOfTxs>11</NbOfTxs>
<TtlIntrBkSttlmAmt Ccy="EUR">111111</TtlIntrBkSttlmAmt>
<IntrBkSttlmDt>2016-11-01</IntrBkSttlmDt>
<SttlmInf>
<SttlmMtd>CLRG</SttlmMtd>
<ClrSys>
<Prtry>ST2</Prtry>
</ClrSys>
</SttlmInf>
<InstgAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstgAgt>
<InstdAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstdAgt>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>MXXXXXX XXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>XXXXXXXXXXXXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
</S2SCTScf:FIToFICstmrCdtTrf>
</S2SCTScf:SCTScfBlkCredTrf>
我尝试了 OPENXML 和 XQuery 函数,但我在声明和使用命名空间(或命名空间uri)时遇到了一些问题。我不熟悉如此复杂的 xml 和 namespaceuri。我需要一个想法来获取 table 下方的数据。我成功地使用了更简单的 xml,即使只有一个命名空间。我已经手动删除了前 11 行,select 波纹管工作得很好......
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @XML = XMLData FROM XMLwithOpenXML where id=6 --this is the xml without first 11 lines
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
SELECT * FROM OPENXML(@hDoc, 'FIToFICstmrCdtTrf/CdtTrfTxInf')
WITH
(
CCY [varchar](100) 'IntrBkSttlmAmt/@Ccy',
IntrBkSttlmAmt [varchar](100) 'IntrBkSttlmAmt',
TxId [varchar](100) 'PmtId/TxId',
EndToEndId [varchar](100) 'PmtId/EndToEndId',
ChrgBr [varchar](100) 'ChrgBr'
--etc
)
EXEC sp_xml_removedocument @hDoc
GO
先说几点
FROM OPENXML
已过时,不应再使用(极少数例外退出)- 您的 XML 在此处包含显式编码
<?xml version=''1.0'' encoding=''UTF-8''?>
。这会迫使您走VARCHAR
路径,这在与非纯拉丁字符的连接中是危险的。最好将其替换为utf-16
并转到NVARCHAR
路径。在这种情况下,您 必须 在 XML 文字前设置一个 "N"。 - 您必须处理相当复杂的命名空间...难以阅读...如果您可以确定没有重复的名称,您可以放弃命名空间声明并放置一个
*:
在每个元素的前面。 - 什么增加了一些额外的努力:你的内部
S2SCTScf:FIToFICstmrCdtTrf
定义了一个新的默认名称空间。我用innerDeflt
. 作为别名
这是变量声明
DECLARE @xml XML=
'<?xml version=''1.0'' encoding=''UTF-8''?>
<S2SCTScf:SCTScfBlkCredTrf xmlns="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:S2SCTScf="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd">
<S2SCTScf:SndgInst>XXXXXXXX</S2SCTScf:SndgInst>
<S2SCTScf:RcvgInst>YYYYYYYY</S2SCTScf:RcvgInst>
<S2SCTScf:SrvcId>SCT</S2SCTScf:SrvcId>
<S2SCTScf:TstCode>P</S2SCTScf:TstCode>
<S2SCTScf:FType>SCF</S2SCTScf:FType>
<S2SCTScf:FileRef>AAAAAAAAAAAAAAAAAAA</S2SCTScf:FileRef>
<S2SCTScf:RoutingInd>IND</S2SCTScf:RoutingInd>
<S2SCTScf:FileBusDt>2016-11-01</S2SCTScf:FileBusDt>
<S2SCTScf:FileCycleNo>01</S2SCTScf:FileCycleNo>
<S2SCTScf:FIToFICstmrCdtTrf xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02">
<GrpHdr>
<MsgId>111111111111111111</MsgId>
<CreDtTm>2016-11-01T15:45:11.0Z</CreDtTm>
<NbOfTxs>11</NbOfTxs>
<TtlIntrBkSttlmAmt Ccy="EUR">111111</TtlIntrBkSttlmAmt>
<IntrBkSttlmDt>2016-11-01</IntrBkSttlmDt>
<SttlmInf>
<SttlmMtd>CLRG</SttlmMtd>
<ClrSys>
<Prtry>ST2</Prtry>
</ClrSys>
</SttlmInf>
<InstgAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstgAgt>
<InstdAgt>
<FinInstnId>
<BIC>XXXXXXXX</BIC>
</FinInstnId>
</InstdAgt>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>MXXXXXX XXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
<TxId>XXXXXXXXXXXXXXXXXXXXXXXXXXXX</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt>
<ChrgBr>SLEV</ChrgBr>
<Dbtr>
<Nm>XXXXXXXXXXXXXXXXX</Nm>
<PstlAdr>
<Ctry>XX</Ctry>
<AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>XXXXXXXXXXXXXXXXXXXXXXXX</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXXXXXXXXXXXXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>XXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Ustrd>
</RmtInf>
</CdtTrfTxInf>
</S2SCTScf:FIToFICstmrCdtTrf>
</S2SCTScf:SCTScfBlkCredTrf>';
这是查询:首先声明所有命名空间。您的节点是纯结构化的 1:1,因此只需在构成 XPath
的元素名称后添加元素名称即可读取它们。只有 <CdtTrfTxInf>
出现两次,需要 1:n-approach
和 APPLY
和 .nodes()
.
在我的示例中,您会为 XML 中隐藏的任何类型的数据获得一个模板。剩下的就看你了。
WITH XMLNAMESPACES(DEFAULT 'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf'
,'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf' as S2SCTScf
,'http://www.w3.org/2001/XMLSchema-instance' AS xsi
,'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd' AS schemaLocation
,'urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02' AS innerDeflt)
SELECT rt.value(N'(S2SCTScf:SndgInst)[1]','nvarchar(max)') AS SndgInst
,rt.value(N'(S2SCTScf:RcvgInst)[1]','nvarchar(max)') AS RcvgInst
--more like this
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:MsgId)[1]','nvarchar(max)') AS MsgId
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:CreDtTm)[1]','datetime') AS CreDtTm
--more like this
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:TtlIntrBkSttlmAmt/@Ccy)[1]','nvarchar(max)') AS TtlIntrBkSttlmAmt_Ccy
,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:TtlIntrBkSttlmAmt)[1]','int') AS TtlIntrBkSttlmAmt
--all nodes are 1:1, just "more of the same"
--But CdtTrfTxInf is there twice, therefore the call to OUTER APPLY rt.nodes()
,cti.value(N'(innerDeflt:PmtId/innerDeflt:EndToEndId)[1]','nvarchar(max)') AS EndToEndId
--all the rest is following the same schema...
FROM @xml.nodes(N'S2SCTScf:SCTScfBlkCredTrf') AS A(rt) --root
OUTER APPLY rt.nodes(N'S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:CdtTrfTxInf') AS B(cti) --CdtTrfTxInf
部分结果(字幕移位...)
SndgInst RcvgInst MsgId CreDtTm TtlIntrBkSttlmAmt_Ccy TtlIntrBkSttlmAmt EndToEndId
XXXXXXXX YYYYYYYY 111111111111111111 2016-11-01 15:45:11.000 EUR 111111 NOTPROVIDED
XXXXXXXX YYYYYYYY 111111111111111111 2016-11-01 15:45:11.000 EUR 111111 NOTPROVIDED