簡體   English   中英

OPENXML將xml導入ms sql - namespace

[英]OPENXML import xml to ms sql - namespace

我使用這個網站很長一段時間,很多次它幫助我解決了各種問題。 這次我被困住了。 我嘗試將一個復雜的xml導入到ms-sql表中。

 <?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函數,但我在聲明和使用命名空間(或namespaceuri)時遇到了一些問題。 我不熟悉這種復雜的xml和namespaceuri。 我需要一個ideea來獲取數據到表格。 我已成功使用更簡單的xml,即使有一個命名空間。 我已經手動刪除了前11行,而選擇的波紋管工作非常精細......

 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 -path,這與非普通拉丁字符的連接很危險。 最好用utf-16替換它,然后去NVARCHAR -path。 在這種情況下,您必須在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>出現兩次,需要使用APPLY.nodes()進行1:n-approach

在我的示例中,您將獲得隱藏在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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM