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:定义type increasecreditafterremittance来暂存解析出来的各字段,这里以xml根节点名称来命名类型,如下:typ和tyb
CREATE OR REPLACE TYPE increasecreditafterremittance AS OBJECT
(
leaguecompanyid VARCHAR2(4000),
companyid VARCHAR2(4000),
remittancevalue INTEGER,
remittancetoken VARCHAR2(32767),
remittancedatetime VARCHAR2(32767),
remark VARCHAR2(32767),
CONSTRUCTOR FUNCTION increasecreditafterremittance RETURN SELF AS RESULT
);
CREATE OR REPLACE TYPE BODY increasecreditafterremittance AS
CONSTRUCTOR FUNCTION increasecreditafterremittance RETURN SELF AS RESULT IS
BEGIN
RETURN;
END;
END;
3:定义对应的解析包程序,把一些公共的解析程序放入公用包中,提高代码复用,如下:分别定义soapdeccommon.pkg和soapdeccommon.pkb
CREATE OR REPLACE PACKAGE soapdeccommon IS
------------------------------------
--author:xy
--date:20181009
--description:用于解析XML中具体类型字段
------------------------------------
FUNCTION decode_string(p_node IN dbms_xmldom.domnode) RETURN VARCHAR2;
FUNCTION decode_int(p_node IN dbms_xmldom.domnode) RETURN INTEGER;
FUNCTION decode_integer(p_node IN dbms_xmldom.domnode) RETURN INTEGER;
FUNCTION decode_calendar(p_node IN dbms_xmldom.domnode) RETURN TIMESTAMP
WITH TIME ZONE;
FUNCTION decd_incr_creditafremittance(p_node IN dbms_xmldom.domnode)
RETURN increasecreditafterremittance;
END soapdeccommon;
CREATE OR REPLACE PACKAGE BODY soapdeccommon IS
------------------------------------
--author:xy
--date:20181009
--description:用于解析XML中具体类型字段
------------------------------------
FUNCTION decode_string(p_node IN dbms_xmldom.domnode) RETURN VARCHAR2 IS
l_children dbms_xmldom.domnodelist;
l_length INTEGER;
l_i INTEGER;
l_child dbms_xmldom.domnode;
l_char_data dbms_xmldom.domcharacterdata;
BEGIN
l_children := dbms_xmldom.getchildnodes(p_node);
l_length := dbms_xmldom.getlength(l_children);
l_i := 0;
WHILE l_i < l_length LOOP
l_child := dbms_xmldom.item(l_children, l_i);
IF dbms_xmldom.getnodetype(l_child) = dbms_xmldom.text_node THEN
l_char_data := dbms_xmldom.makecharacterdata(l_child);
RETURN dbms_xmldom.getdata(l_char_data);
END IF;
l_i := l_i + 1;
END LOOP;
RETURN '';
END;
FUNCTION decode_int(p_node IN dbms_xmldom.domnode) RETURN INTEGER IS
BEGIN
RETURN to_number(decode_string(p_node));
END;
FUNCTION decode_integer(p_node IN dbms_xmldom.domnode) RETURN INTEGER IS
BEGIN
RETURN to_number(decode_string(p_node));
END;
FUNCTION decode_calendar(p_node IN dbms_xmldom.domnode) RETURN TIMESTAMP
WITH TIME ZONE IS
l_decode_result VARCHAR2(32767);
l_calendar TIMESTAMP WITH TIME ZONE;
BEGIN
l_decode_result := decode_string(p_node);
l_calendar := NULL;
BEGIN
l_calendar := to_timestamp_tz(l_decode_result,
'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM');
EXCEPTION
WHEN OTHERS THEN
BEGIN
BEGIN
l_calendar := to_timestamp_tz(l_decode_result,
'YYYY-MM-DD"T"HH24:MI:SS');
EXCEPTION
WHEN OTHERS THEN
BEGIN
l_calendar := to_timestamp_tz(l_decode_result,
'YYYY-MM-DD"T"HH24:MI:SS"Z"');
END;
END;
END;
END;
RETURN l_calendar;
END;
FUNCTION decd_incr_creditafremittance(p_node IN dbms_xmldom.domnode)
RETURN increasecreditafterremittance IS
l_obj increasecreditafterremittance;
l_children dbms_xmldom.domnodelist;
l_length INTEGER;
l_i INTEGER;
l_child dbms_xmldom.domnode;
l_name VARCHAR2(32767);
l_decode_result VARCHAR2(32767);
BEGIN
l_obj := increasecreditafterremittance();
l_children := dbms_xmldom.getchildnodes(p_node);
l_length := dbms_xmldom.getlength(l_children);
FOR l_i IN 0 .. (l_length - 1) LOOP
l_child := dbms_xmldom.item(l_children, l_i);
IF dbms_xmldom.getnodetype(l_child) != dbms_xmldom.element_node THEN
CONTINUE;
END IF;
l_name := dbms_xmldom.getlocalname(dbms_xmldom.makeelement(l_child));
IF l_name = 'LeagueCompanyId' THEN
l_decode_result := decode_string(l_child);
l_obj.leaguecompanyid := l_decode_result;
END IF;
IF l_name = 'CompanyId' THEN
l_decode_result := decode_string(l_child);
l_obj.companyid := l_decode_result;
END IF;
IF l_name = 'RemittanceValue' THEN
l_decode_result := decode_int(l_child);
l_obj.remittancevalue := l_decode_result;
END IF;
IF l_name = 'RemittanceToken' THEN
l_decode_result := decode_string(l_child);
l_obj.remittancetoken := l_decode_result;
END IF;
IF l_name = 'RemittanceDateTime' THEN
l_decode_result := decode_string(l_child);
l_obj.remittancedatetime := l_decode_result;
END IF;
IF l_name = 'Remark' THEN
l_decode_result := decode_string(l_child);
l_obj.remark := l_decode_result;
END IF;
END LOOP;
RETURN l_obj;
END;
END soapdeccommon;
4:编写测试用例进行测试,如下测试用例:
declare
request_clob clob :='<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>';
req_doc DBMS_XMLDOM.domdocument;
requestNode XMLDOM.domnode;
l_request increasecreditafterremittance;
begin
l_request := increasecreditafterremittance();
req_doc := dbms_xmldom.newDOMDocument (request_clob);
requestNode := XMLDOM.item (xmldom.getelementsbytagname (req_doc,'RemittanceParameterItem'), 0);
l_request := soapdeccommon.decd_incr_creditafremittance(requestNode);
raise_application_error(-20201,'l_request.LeagueCompanyId:'||l_request.leaguecompanyid||'--'||'l_request.CompanyId:'||l_request.CompanyId||'--'||'l_request.RemittanceValue:'||l_request.RemittanceValue);
end;
PLSQL DEVELOPER运行测试用例,得出如下图所示结果:
5:经过上述测试,则对于接收来自调用者的xml信息,解析并进行数据库相关操作,如下存储过程功能即:解析接收的xml,对其进行分析,然后插入相关数据库表中
CREATE OR REPLACE PROCEDURE incrcreditafremittance_read(p_request_clob IN CLOB,
p_code IN OUT NUMBER,
p_err_mesg IN OUT VARCHAR2) AS
------------------------------------------------
--author:xy
--date:20181009
--description:获取RFC接口下发的电子付款单,向公司收款单中写入
------------------------------------------------
req_doc dbms_xmldom.domdocument;
requestnode xmldom.domnode;
l_request increasecreditafterremittance;
v_table_id ad_table.id%TYPE; --公司收款单g_receive表的id
v_docno g_receive.docno%TYPE; ----公司收款单g_receive单据编号
v_g_receive_id g_receive.id%TYPE;
BEGIN
p_code := 1;
p_err_mesg := 'FAILED:INSERTION FAILED';
l_request := increasecreditafterremittance();
req_doc := dbms_xmldom.newdomdocument(p_request_clob);
requestnode := xmldom.item(xmldom.getelementsbytagname(req_doc,
'RemittanceParameterItem'),
0);
l_request := soapdeccommon.decd_incr_creditafremittance(requestnode);
--获取表g_receive的id
SELECT id
INTO v_table_id
FROM ad_table
WHERE NAME = upper('g_receive');
--自动生成单据编号
SELECT t.sequencename
INTO v_docno
FROM ad_column t
WHERE t.ad_table_id = v_table_id
AND t.dbname = 'DOCNO';
v_docno := get_sequenceno(v_docno, 37);
v_g_receive_id := get_sequences('G_RECEIVE');
/*raise_application_error(-20201,
to_number(REPLACE(substr(l_request.remittancedatetime,
1, 10), '-', '')));*/
INSERT INTO g_receive
(id, ad_client_id, ad_org_id, docno, billdate, g_company_id,
g_acc_company_id, c_currency_id, c_tranrency_id, g_acctype_id,
feereceive, description, status, ownerid, modifierid, creationdate,
statuserid, statustime, modifieddate, isactive)
SELECT v_g_receive_id, 37, 27, v_docno,
to_number(REPLACE(substr(l_request.remittancedatetime, 1, 10),
'-', '')), gc.id, gc1.id, cur.id, cur.id,
gac.id, l_request.remittancevalue, l_request.remark, 1, 893, 893,
SYSDATE, NULL, NULL, SYSDATE, 'Y'
FROM dual
JOIN g_company gc
ON (gc.sap_code = l_request.leaguecompanyid)
JOIN g_company gc1
ON (gc1.sap_code = l_request.companyid)
JOIN c_currency cur
ON (cur.iso_code = 'CNY')
JOIN g_acctype gac
ON (gac.code = '001' AND gac.name = '默认账户');
IF SQL%ROWCOUNT > 0 THEN
g_receive_submit(v_g_receive_id, p_code, p_err_mesg);
p_code := 0;
p_err_mesg := 'SUCCESS';
END IF;
EXCEPTION
WHEN OTHERS THEN
p_code := 1;
p_err_mesg := 'FAILED:' || SQLERRM;
END;