zoukankan      html  css  js  c++  java
  • PLSQL 解析XML示例1

    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;
    

      

  • 相关阅读:
    关于近期
    Tips on Importons and Irradiance Particles in mental ray
    给她的歌
    Fatal In Code Generation Of Visual C++
    kdtree vs octree
    疯子的胜利——记6.18毕业晚会
    转凉
    事件与委托的匿名方法使用方法示例
    VS2008使用技巧
    硬链接和软连接的区别
  • 原文地址:https://www.cnblogs.com/Jeffrey-xu/p/9762463.html
Copyright © 2011-2022 走看看