Blank xml namespace in child nodes in SQL Server

前端 未结 1 933
醉话见心
醉话见心 2020-12-21 14:59

Hi i need help with the following in sql:

I need to create a xml file in this format



        
相关标签:
1条回答
  • 2020-12-21 15:13

    EDIT 2: I finally found a way to avoid repeated namespaces. First you create the nested XML without the namespace, then you join it:

    UPDATE (Dec 2017)

    This workaround is still not really helpfull actually. The namespaces xmlns="" are taken as *everything inside is not within a namespace... You might convert the result to NVARCHAR(MAX) and use REPLACE to get rid of xmlns="". Then you can re-convert the string to XML. Shame on Microsoft, that the 10(!!) years old issue (see link below) is still unsolved. Please go there and vote!

    DECLARE @lim_Live_Inbound TABLE(lim_msg_id VARCHAR(100),lim_request_transaction_id VARCHAR(100),client_name VARCHAR(100));
    INSERT INTO @lim_Live_Inbound VALUES
     ('021/00210006/20160225/000002','00012016-02-25000000023','Mr Piet')
    ,('021/00210006/20160225/000002','00012016-02-25000000022','Mrs Name');
    
    DECLARE @nestedXMLs TABLE(MsgId VARCHAR(100),nestedXML XML);
    
    WITH GrpMsg AS
    (
        SELECT DISTINCT lim_msg_id AS MsgId
        FROM @lim_Live_Inbound
    )
    INSERT INTO @nestedXMLs 
    SELECT MsgId 
         ,(
            SELECT innerTbl.lim_request_transaction_id AS OrgnlMsgId
                  ,innerTbl.client_name AS name
            FROM @lim_Live_Inbound AS innerTbl
            WHERE innerTbl.lim_msg_id=GrpMsg.MsgId
            FOR XML PATH('OrgnlGrpInfAndSts'),TYPE
          ) 
    FROM GrpMsg;
    
    WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:001.002.001.04')
    ,GrpMsg AS
    (
        SELECT DISTINCT lim_msg_id AS MsgId
        FROM @lim_Live_Inbound
    )
    SELECT GrpMsg.MsgId AS [GrpHdr/MsgId]
          ,n.nestedXML AS [node()]
    FROM GrpMsg
    INNER JOIN @nestedXMLs AS n ON GrpMsg.MsgId=n.MsgId
    FOR XML PATH('FIToFIPmtStsRp'),ROOT('Document')
    

    The result

    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04">
      <FIToFIPmtStsRp>
        <GrpHdr>
          <MsgId>021/00210006/20160225/000002</MsgId>
        </GrpHdr>
        <OrgnlGrpInfAndSts xmlns="">
          <OrgnlMsgId>00012016-02-25000000023</OrgnlMsgId>
          <name>Mr Piet</name>
        </OrgnlGrpInfAndSts>
        <OrgnlGrpInfAndSts xmlns="">
          <OrgnlMsgId>00012016-02-25000000022</OrgnlMsgId>
          <name>Mrs Name</name>
        </OrgnlGrpInfAndSts>
      </FIToFIPmtStsRp>
    </Document>
    

    You'd use CAST(REPLACE(CAST(TheXMLHere AS NVARCHAR(MAX)),' xmlns=""','') AS XML) to get rid of the wrong empty namespaces....

    EDIT: new approach to fit your sample data

    This is repeating the namespace - but this is syntactically correct, yet annoying (read here: https://connect.microsoft.com/SQLServer/feedback/details/265956/suppress-namespace-attributes-in-nested-select-for-xml-statements)

    DECLARE @lim_Live_Inbound TABLE(lim_msg_id VARCHAR(100),lim_request_transaction_id VARCHAR(100),client_name VARCHAR(100));
    INSERT INTO @lim_Live_Inbound VALUES
     ('021/00210006/20160225/000002','00012016-02-25000000023','Mr Piet')
    ,('021/00210006/20160225/000002','00012016-02-25000000022','Mrs Name');
    
    WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:001.002.001.04')
    ,GrpMsg AS
    (
        SELECT DISTINCT lim_msg_id AS MsgId
        FROM @lim_Live_Inbound
    )
    SELECT MsgId AS [GrpHdr/MsgId]
         ,(
            SELECT innerTbl.lim_request_transaction_id AS OrgnlMsgId
                  ,innerTbl.client_name AS name
            FROM @lim_Live_Inbound AS innerTbl
            WHERE innerTbl.lim_msg_id=GrpMsg.MsgId
            FOR XML PATH('OrgnlGrpInfAndSts'),TYPE
          ) 
    FROM GrpMsg
    FOR XML PATH('FIToFIPmtStsRp'),ROOT('Document')
    

    The result

    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04">
      <FIToFIPmtStsRp>
        <GrpHdr>
          <MsgId>021/00210006/20160225/000002</MsgId>
        </GrpHdr>
        <OrgnlGrpInfAndSts xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04">
          <OrgnlMsgId>00012016-02-25000000023</OrgnlMsgId>
          <name>Mr Piet</name>
        </OrgnlGrpInfAndSts>
        <OrgnlGrpInfAndSts xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04">
          <OrgnlMsgId>00012016-02-25000000022</OrgnlMsgId>
          <name>Mrs Name</name>
        </OrgnlGrpInfAndSts>
      </FIToFIPmtStsRp>
    </Document>
    

    This is the first approach

    I don't know where your data comes from, but - absolutely hard coded - this was the approach:

    WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:001.002.001.04')
    SELECT 0 AS [GrpHdr/MsgId]
          ,0 AS [OrgnlGrpInfAndSts/OrgnlMsgId]
    FOR XML PATH('FIToFIPmtStsRp'),ROOT('Document')
    

    The result

    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04">
      <FIToFIPmtStsRp>
        <GrpHdr>
          <MsgId>0</MsgId>
        </GrpHdr>
        <OrgnlGrpInfAndSts>
          <OrgnlMsgId>0</OrgnlMsgId>
        </OrgnlGrpInfAndSts>
      </FIToFIPmtStsRp>
    </Document>
    
    0 讨论(0)
提交回复
热议问题