PLSQL构造XML实例(XML ENCODE)

本篇实例基于《PLSQL解析XML示例1》中的type IncreaseCreditAfterRemittance进行构造XML。

1.构造如下格式XML数据:

<ns1:IncreaseCreditAfterRemittance xmlns:ns1="http://tempuri.org/">
 <ns1:parameters>
  <ns1:RemittanceParameterItem>
    <ns1:LeagueCompanyId>2001116</ns1:LeagueCompanyId>
    <ns1:CompanyId>1000</ns1:CompanyId>
    <ns1:RemittanceValue>65000.0</ns1:RemittanceValue>
    <ns1:RemittanceToken>9591503</ns1:RemittanceToken>
    <ns1:RemittanceDateTime>2018-09-26T14:51:22.0Z</ns1:RemittanceDateTime>
    <ns1:Remark>640001391210002018</ns1:Remark>
   </ns1:RemittanceParameterItem>
  </ns1:parameters>
</ns1:IncreaseCreditAfterRemittance>

 

2.考虑到构造XML过程中使用到oracle包程序DBMS_XMLDOM中的类型DOMDocument特殊型,现将其封装在新定义的包中,定义如下XmlResponse:

CREATE OR REPLACE PACKAGE XmlResponse IS response_doc DBMS_XMLDOM.DOMDocument ;
END XmlResponse ;

CREATE OR REPLACE PACKAGE BODY XmlResponse IS END XmlResponse ;

 

3:定义公共构造XML包程序:SoapEncCommon,将构造公共具体类型标签的方法和特定XML构造程序封装在其中,方便代码复用,便于维护。包程序如下:

CREATE OR REPLACE PACKAGE SoapEncCommon IS
    ------------------------------------
    --author:xy
    --date:20181009
    --description:用于构造XML中具体类型字段
    ------------------------------------
FUNCTION encode_string (p_obj IN VARCHAR2 , p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode ;
FUNCTION encode_int (p_obj IN INTEGER , p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode ;
FUNCTION encode_calendar (p_obj IN TIMESTAMP WITH TIME ZONE, p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode ;
FUNCTION encode_integer (p_obj IN INTEGER , p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode ;
FUNCTION encd_incr_creditafremittance(p_obj IN increasecreditafterremittance ) RETURN DBMS_XMLDOM.DOMDocument;
FUNCTION encode_response(p_obj IN increasecreditafterremittance,p_tag IN VARCHAR2) RETURN DBMS_XMLDOM.DOMNode;
END SoapEncCommon ;




CREATE OR REPLACE PACKAGE BODY SoapEncCommon IS
    ------------------------------------
    --author:xy
    --date:20181009
    --description:用于构造XML中具体类型字段
    ------------------------------------
FUNCTION encode_string (p_obj IN VARCHAR2 , p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode  IS
l_return_node DBMS_XMLDOM.DOMNode ; l_node4 DBMS_XMLDOM.DOMNode ; BEGIN
    l_node4  := DBMS_XMLDOM.makeNode (DBMS_XMLDOM.createElement (XmlResponse.response_doc , p_tag ));
    IF  p_obj  IS NOT NULL THEN
        BEGIN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node4 ,
                                                       DBMS_XMLDOM.
                                                       makeNode (DBMS_XMLDOM.createTextNode (XmlResponse.response_doc , p_obj )));
        END;
    ELSE
        BEGIN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node4 ,
                                                       DBMS_XMLDOM.makeNode (DBMS_XMLDOM.createTextNode (XmlResponse.response_doc , ' ')));
        END;
    END IF;
    RETURN l_node4 ;
END;
FUNCTION encode_int (p_obj IN INTEGER , p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode  IS
BEGIN
    IF  p_obj  IS NOT NULL THEN BEGIN RETURN encode_string (TO_CHAR (p_obj ), p_tag ); END; ELSE
        BEGIN RETURN encode_string (' ', p_tag ); END; END IF;
END;
FUNCTION encode_calendar (p_obj IN TIMESTAMP WITH TIME ZONE, p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode  IS
BEGIN RETURN encode_string (TO_CHAR (p_obj , 'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM'), p_tag ); END;
FUNCTION encode_integer (p_obj IN INTEGER , p_tag IN VARCHAR2 ) RETURN DBMS_XMLDOM.DOMNode  IS
BEGIN
    IF  p_obj  IS NOT NULL THEN BEGIN RETURN encode_string (TO_CHAR (p_obj ), p_tag ); END; ELSE
        BEGIN RETURN encode_string (' ', p_tag ); END; END IF;
END;


FUNCTION encode_response(p_obj IN increasecreditafterremittance,p_tag IN VARCHAR2) RETURN DBMS_XMLDOM.DOMNode  IS
l_element_1 DBMS_XMLDOM.DOMElement ;
l_return_node DBMS_XMLDOM.DOMNode ;
l_element DBMS_XMLDOM.DOMElement ;
l_node0 DBMS_XMLDOM.DOMNode ;
l_node1 DBMS_XMLDOM.DOMNode ;
l_node2 DBMS_XMLDOM.DOMNode ;
l_node3 DBMS_XMLDOM.DOMNode ;
l_node4 DBMS_XMLDOM.DOMNode ;
BEGIN
    l_element  := DBMS_XMLDOM.createElement (XmlResponse.response_doc , 'ns1:parameters');
    l_node1  := DBMS_XMLDOM.makeNode (l_element );
    
    BEGIN
        l_element_1  := DBMS_XMLDOM.createElement (XmlResponse.response_doc , 'ns1:RemittanceParameterItem');
        l_node2  := DBMS_XMLDOM.makeNode (l_element_1 );
    END;
    
    BEGIN
        IF  p_obj.leaguecompanyid IS NOT NULL THEN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node2, encode_string (p_obj.leaguecompanyid , 'ns1:LeagueCompanyId'));
        END IF;

        IF  p_obj.companyid IS NOT NULL THEN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node2, encode_string (p_obj.companyid , 'ns1:CompanyId'));
        END IF;

        IF  p_obj.remittancevalue IS NOT NULL THEN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node2, encode_string (p_obj.remittancevalue , 'ns1:RemittanceValue'));
        END IF;

        IF  p_obj.remittancetoken IS NOT NULL THEN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node2, encode_string (p_obj.remittancetoken , 'ns1:RemittanceToken'));
        END IF;

        IF  p_obj.remittancedatetime IS NOT NULL THEN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node2, encode_string (p_obj.remittancedatetime , 'ns1:RemittanceDateTime'));
        END IF;

        IF  p_obj.remark IS NOT NULL THEN
            l_return_node  := DBMS_XMLDOM.appendChild (l_node2, encode_string (p_obj.remark , 'ns1:Remark'));
        END IF;
    END;

    BEGIN
        l_return_node  := DBMS_XMLDOM.appendChild (l_node1 , l_node2);
    END;
    
    BEGIN
        l_element  := DBMS_XMLDOM.createElement (XmlResponse.response_doc , p_tag );
        l_node0  := DBMS_XMLDOM.makeNode (l_element );
        l_return_node  := DBMS_XMLDOM.appendChild (l_node0, l_node1 );
    END;

    RETURN l_node0 ;
END;

FUNCTION encd_incr_creditafremittance(p_obj IN increasecreditafterremittance ) RETURN DBMS_XMLDOM.DOMDocument  IS
l_response_node DBMS_XMLDOM.DOMNode ; l_element DBMS_XMLDOM.DOMElement ; l_node DBMS_XMLDOM.DOMNode ; l_fcall_tmp DBMS_XMLDOM.DOMNode ;
BEGIN
    XmlResponse.response_doc  := DBMS_XMLDOM.newDOMDocument ();
    l_response_node  := encode_response(p_obj , 'ns1:IncreaseCreditAfterRemittance');
    l_element  := DBMS_XMLDOM.makeElement (l_response_node );
    l_node  := DBMS_XMLDOM.makeNode (XmlResponse.response_doc );
    l_fcall_tmp  := DBMS_XMLDOM.appendChild (l_node , l_response_node );
    DBMS_XMLDOM.setAttribute (l_element , 'xmlns:ns1',
                              'http://tempuri.org/');
    RETURN XmlResponse.response_doc ;
END;
END SoapEncCommon ;

 

4.编写测试用例,来验证构造XML程序功能是否正确,测试用例如下:

DECLARE 

   l_request    increasecreditafterremittance;
   responseDoc DBMS_XMLDOM.DOMDOCUMENT;
   l_xmltype XMLTYPE;
   response_clob clob;
   
begin
   l_request := increasecreditafterremittance();
   
   l_request.leaguecompanyid := '2001116';
   l_request.companyid := '1000';
   l_request.remittancevalue := '6500.0';
   l_request.remittancetoken := '9591503';
   l_request.remittancedatetime := '2018-09-26T14:51:22.0Z';
   l_request.remark := '640001391210002018';

   responseDoc := SoapEncCommon.encd_incr_creditafremittance(l_request);
   l_xmltype := dbms_xmldom.getXmlType(responseDoc);
   dbms_xmldom.freeDocument(responseDoc);
   response_clob := l_xmltype.getClobVal;
   raise_application_error(-20201,'response xml:'||response_clob);
end;

测试运行结果如下所示:

 

5.以上只是针对简单的XML构造做简单的展示,若要构造复杂的XML格式数据,如:带嵌套循环的格式数据,其实也不难,只需根据对应的循环标签的特征,在类型中新增用于存储循环标签值的变量(成员),并且在特定构造程序中循环遍历此变量,循环依次追加相同标签不同值的XML格式数据。

 

posted @ 2019-12-15 14:12  MorePrograms  阅读(461)  评论(0编辑  收藏  举报