本篇实例基于《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;
测试运行结果如下所示:

(注:源程序各标签的值用成了一个,导致构造出的XML数据中标签值都一样)
5.以上只是针对简单的XML构造做简单的展示,若要构造复杂的XML格式数据,如:带嵌套循环的格式数据,其实也不难,只需根据对应的循环标签的特征,在类型中新增用于存储循环标签值的变量(成员),并且在特定构造程序中循环遍历此变量,循环依次追加相同标签不同值的XML格式数据。
原文:https://www.cnblogs.com/Jeffrey-xu/p/12044001.html