数据库生成XML脚本

来源:互联网 发布:毛戈平化妆学校 知乎 编辑:程序博客网 时间:2024/04/30 12:18

CREATE OR REPLACE PACKAGE zte_fbp_xml_util_pkg IS  /* ==========================================================================+  版权信息:版权所有(c) 2004,中兴通讯股份有限公司  文件名称:zte_fbp_xml_util_pkg  版 本 号:v1.0.0  创 建 者:  创建日期:2004-09-06 16:51:00  内容摘要:网上支付中的xml公用处理包

  更改历史:            更改人 更改日期 更改原因     韩荣华 2005-02-20 在write_element_string过程中对xml值中有‘&’‘<>’等这些符号进行处理  +===========================================================================*/

  --直接用CLOB处理xml的新接口1:创建xml document,对应write_end_document  PROCEDURE write_start_document(p_clob IN OUT NOCOPY CLOB);

  --直接用CLOB处理xml的新接口2:关闭xml document,对应write_end_document  PROCEDURE write_end_document(p_clob IN OUT NOCOPY CLOB);

  --直接用CLOB处理xml的新接口3:创建节点,对应write_end_element  PROCEDURE write_start_element(p_clob IN OUT NOCOPY CLOB,p_element_name VARCHAR2);

  --直接用CLOB处理xml的新接口4:关闭节点,对应write_start_element  PROCEDURE write_end_element(p_clob IN OUT NOCOPY CLOB,p_element_name VARCHAR2);

  --直接用CLOB处理xml的新接口5:创建子节点及值,并增加到CLOB中  PROCEDURE write_element_string(p_clob IN OUT NOCOPY CLOB,p_node_name VARCHAR2,p_node_value VARCHAR2);  PROCEDURE write_element_string(p_clob IN OUT NOCOPY CLOB,p_node_name VARCHAR2,p_node_value NUMBER);

  --直接用CLOB处理xml的新接口6:获取表多行数据增加到CLOB中  PROCEDURE write_multi_lines(p_clob IN OUT NOCOPY CLOB,p_sql VARCHAR2,p_rowset_tag_name VARCHAR2,p_row_tag_name VARCHAR2);

  -- 获取 Element 下面的指定节点名称的对应值  -- 值为空时,返回NULL; 不存在此节点名称时, 程序抛错  FUNCTION get_node_value(p_elem xmldom.DOMElement, p_node_name VARCHAR2) RETURN VARCHAR2;

  -- 获取 Element 下面的指定节点和属性名称的对应属性值  -- 值为空时,返回NULL; 不存在此节点名称时, 程序抛错; 不存在此属性时返回NULL  FUNCTION get_attr_value(p_elem xmldom.DOMElement, p_node_name VARCHAR2, p_attr_name VARCHAR2) RETURN VARCHAR2;

  -- 获取 Element 本身属性名称的对应属性值  -- 值为空时,返回NULL; 不存在此属性时返回NULL  FUNCTION get_attr_value(p_elem xmldom.DOMElement, p_attr_name VARCHAR2) RETURN VARCHAR2;

  -- 在 xmldom 中对象的节点下增加子节点及值  FUNCTION create_son_node(p_doc xmldom.DOMDocument,p_node xmldom.DOMNode,p_node_name VARCHAR2,p_node_value VARCHAR2) RETURN xmldom.DOMNode;

  -- 在 xmldom 中对象的节点下增加子节点  FUNCTION create_son_node(p_doc xmldom.DOMDocument,p_node xmldom.DOMNode,p_node_name VARCHAR2) RETURN xmldom.DOMNode;

   /*================================================================*/  PROCEDURE import_node (    p_doc  xmldom.DOMDocument,           -- 声明xmldomc对象    p_parentnode  xmldom.DOMNode,        -- 声明节点对象(xml需要加在下面)    p_xml  VARCHAR2                      -- 输入xml字符串  );    /*==============================================================-+  名    称:import_node  内容摘要:将一段xml字符串创建到指定的节点下。

  调    用:  被调用  :  创建者  :  创建日期:2004-09-14  被访问表:  被更改表:  输    入:

                    p_doc  xmldom.DOMDocument;           -- 声明xmldomc对象                    p_parentnode  xmldom.DOMNode;        -- 声明节点对象(xml需要加在下面)                    p_xml  VARCHAR2                          -- 输入xml字符串  输    出:

  返 回 值:  其    它:  更改历史:              更改日期    更改人               更改说明

  +================================================================*/   /*================================================================*/  PROCEDURE import_node (    p_doc  xmldom.DOMDocument,           -- 声明xmldomc对象    p_parentnode  xmldom.DOMNode,        -- 声明节点对象(xml需要加在下面)    p_xml  CLOB                          -- 输入xml CLOB  );    /*==============================================================-+  名    称:import_node  内容摘要:将一段xml字符串创建到指定的节点下。

  调    用:  被调用  :  创建者  :  创建日期:2004-10-10  被访问表:  被更改表:  输    入:

                    p_doc  xmldom.DOMDocument;           -- 声明xmldomc对象                    p_parentnode  xmldom.DOMNode;        -- 声明节点对象(xml需要加在下面)                    p_xml  CLOB                          -- 输入xml CLOB  输    出:

  返 回 值:  其    它:  更改历史:              更改日期    更改人               更改说明

  +================================================================*/

  PROCEDURE get_node_xml(        p_xml_in   VARCHAR2 ,        -- 输入xml        p_node_name    VARCHAR2 ,    -- 声明要要取的节点对象名称        p_xml_out OUT  VARCHAR2      -- 输出xml  );  /*==============================================================-+  名    称:get_node_xml  内容摘要:返回p_xml_in字符串中指定的节点名称的下的字符串

  调    用:  被调用  :  创建者  :zhangxiaoyan  创建日期:2004-09-14  被访问表:  被更改表:  输    入:

                    p_xml_in      CLOB       -- 输入xml CLOB                    p_parentnode  VARCHAR2       -- 指定的节点名称                    p_xml_out     CLOB       -- 输出xml CLOB  输    出:

  返 回 值:  其    它:  更改历史:              更改日期    更改人               更改说明

  +================================================================*/  PROCEDURE get_node_xml(        p_xml_in  CLOB ,        -- 输入xml CLOB        p_node_name  VARCHAR2 , -- 声明要要取的节点对象名称        p_xml_out OUT CLOB      -- 输出xml CLOB  );  /*==============================================================-+  名    称:get_node_xml  内容摘要:返回p_xml_in字符串中指定的节点名称的下的字符串

  调    用:  被调用  :  创建者  :zhangxiaoyan  创建日期:2004-10-11  被访问表:  被更改表:  输    入:

                    p_xml_in      CLOB       -- 输入xml CLOB                    p_parentnode  VARCHAR2   -- 指定的节点名称                    p_xml_out     CLOB       -- 输出xml CLOB  输    出:

  返 回 值:  其    它:  更改历史:              更改日期    更改人               更改说明

  +================================================================*/END zte_fbp_xml_util_pkg;/CREATE OR REPLACE PACKAGE BODY zte_fbp_xml_util_pkg IS  --直接用CLOB处理xml的新接口1:创建xml document,对应write_end_document  PROCEDURE write_start_document(p_clob IN OUT NOCOPY CLOB) IS    v_node VARCHAR2(50);  BEGIN    dbms_lob.createtemporary(p_clob,TRUE); v_node := '<?xml version="1.0" encoding="gb2312" ?>'; dbms_lob.writeappend(p_clob,LENGTH(v_node),v_node);  END write_start_document;

  --直接用CLOB处理xml的新接口2:关闭xml document,对应write_end_document  PROCEDURE write_end_document(p_clob IN OUT NOCOPY CLOB) IS  BEGIN    NULL;  END write_end_document;

  --直接用CLOB处理xml的新接口3:创建节点,对应write_end_element  PROCEDURE write_start_element(p_clob IN OUT NOCOPY CLOB,p_element_name VARCHAR2) IS    v_node VARCHAR2(50);  BEGIN    v_node := '<'||p_element_name||'>'; dbms_lob.writeappend(p_clob,LENGTH(v_node),v_node);  END write_start_element;

  --直接用CLOB处理xml的新接口4:关闭节点,对应write_start_element  PROCEDURE write_end_element(p_clob IN OUT NOCOPY CLOB,p_element_name VARCHAR2) IS    v_node VARCHAR2(50);  BEGIN    v_node := '</'||p_element_name||'>'; dbms_lob.writeappend(p_clob,LENGTH(v_node),v_node);  END write_end_element;

  --直接用CLOB处理xml的新接口5:创建子节点及值,并增加到CLOB中  --2005-02-20 韩荣华  对xml值中有‘&’‘<>’等这些符号进行处理  PROCEDURE write_element_string(p_clob IN OUT NOCOPY CLOB,p_node_name VARCHAR2,p_node_value VARCHAR2) IS    v_node VARCHAR2(3767);     -- 节点    l_isfiler NUMBER := 0;  -- 是否使用替换后的值    v_new_value VARCHAR2(3767);  BEGIN    v_new_value := p_node_value;    IF INSTR(v_new_value,'&') > 0 THEN      v_new_value := REPLACE(v_new_value,'&','&amp;');      l_isfiler := 1;    END IF;    IF INSTR(v_new_value,'<') > 0 THEN      v_new_value := REPLACE(v_new_value,'<','&lt;');      l_isfiler := 1;    END IF;    IF INSTR(v_new_value,'>') > 0 THEN      v_new_value := REPLACE(v_new_value,'>','&gt;');      l_isfiler := 1;    END IF;    IF l_isfiler=0 THEN      v_node := '<'||p_node_name||'>'||p_node_value||'</'||p_node_name||'>';    ELSE      v_node := '<'||p_node_name||'>'||v_new_value||'</'||p_node_name||'>';    END IF;    dbms_lob.writeappend(p_clob,LENGTH(v_node),v_node);  END write_element_string;  PROCEDURE write_element_string(p_clob IN OUT NOCOPY CLOB,p_node_name VARCHAR2,p_node_value NUMBER) IS    v_node VARCHAR2(3767);     -- 节点  BEGIN    v_node := '<'||p_node_name||'>'||p_node_value||'</'||p_node_name||'>'; dbms_lob.writeappend(p_clob,LENGTH(v_node),v_node);  END write_element_string;

  --直接用CLOB处理xml的新接口6:获取表多行数据增加到CLOB中  PROCEDURE write_multi_lines(p_clob IN OUT NOCOPY CLOB,p_sql VARCHAR2,p_rowset_tag_name VARCHAR2,p_row_tag_name VARCHAR2) IS    queryCtx dbms_xmlquery.ctxType; -- 使用XML-SQL Utility (XSU)    v_subxml CLOB;          -- 得到的子xml结果    v_node VARCHAR2(32767);     -- 节点    n_length NUMBER;                        --CLOB的总长度    n_read_size NUMBER := 16000;     --一次读取CLOB的大小    n_loop_count NUMBER := 1;         --循环读取CLOB的次数  BEGIN    queryCtx := dbms_xmlquery.newContext(p_sql);    dbms_xmlquery.setRowSetTag(queryCtx,p_rowset_tag_name); -- sets rowset tag name    dbms_xmlquery.setRowTag(queryCtx,p_row_tag_name); -- sets the row tag name    v_subxml := dbms_xmlquery.getXML(queryCtx); -- get the result    dbms_xmlquery.closeContext(queryCtx);  -- close the query handle;

    --循环读入出参中    n_loop_count := 1;    n_length := dbms_lob.GETLENGTH(v_subxml);    WHILE n_length > n_read_size*(n_loop_count-1) LOOP IF n_loop_count=1 THEN   --去掉<?xml version = '1.0'?>24个长度   v_node := dbms_lob.SUBSTR(v_subxml,n_read_size-23,24); ELSE   v_node := dbms_lob.SUBSTR(v_subxml,n_read_size,n_read_size*(n_loop_count-1)+1); END IF; dbms_lob.writeappend(p_clob,LENGTH(v_node),v_node);

 n_loop_count := n_loop_count + 1;    END LOOP;  END write_multi_lines;

 

  -- 获取 Element 下面的指定节点名称的对应值  -- 值为空时,返回NULL; 不存在此节点名称时, 程序抛错  FUNCTION get_node_value(p_elem xmldom.DOMElement, p_node_name VARCHAR2) RETURN VARCHAR2 IS    result VARCHAR2(500);    ndl xmldom.DOMNodeList;      -- 声明节点列表    node xmldom.DOMNode;         -- 声明节点对象  BEGIN    ndl := xmldom.getElementsByTagName(p_elem,p_node_name);    node := xmldom.item(ndl, 0);    node := xmldom.getFirstChild(node);    IF xmldom.isNull(node) THEN      result := NULL;    ELSE      result := xmldom.getNodeValue(node);    END IF;    RETURN(result);  END get_node_value;  -- 获取 Element 下面的指定节点和属性名称的对应属性值  -- 值为空时,返回NULL; 不存在此节点名称时, 程序抛错; 不存在此属性时返回NULL  FUNCTION get_attr_value(p_elem xmldom.DOMElement, p_node_name VARCHAR2, p_attr_name VARCHAR2) RETURN VARCHAR2 IS    result VARCHAR2(500);    ndl xmldom.DOMNodeList;          -- 声明节点列表    node xmldom.DOMNode;             -- 声明节点对象    elem xmldom.DOMElement;          -- 声明Element对象    attr xmldom.DOMAttr;             -- 声明Element对象  BEGIN    ndl := xmldom.getElementsByTagName(p_elem,p_node_name);    node := xmldom.item(ndl, 0);    elem := xmldom.makeElement(node);    attr := xmldom.getAttributeNode(elem,p_attr_name);    IF xmldom.isNull(attr) THEN      result := NULL;    ELSE      result := xmldom.getValue(attr);    END IF;    RETURN(result);  END get_attr_value;  -- 获取 Element 本身属性名称的对应属性值  -- 值为空时,返回NULL; 不存在此属性时返回NULL  FUNCTION get_attr_value(p_elem xmldom.DOMElement, p_attr_name VARCHAR2) RETURN VARCHAR2 IS    result VARCHAR2(500);    attr xmldom.DOMAttr;             -- 声明Element对象  BEGIN    attr := xmldom.getAttributeNode(p_elem,p_attr_name);    IF xmldom.isNull(attr) THEN      result := NULL;    ELSE      result := xmldom.getValue(attr);    END IF;    RETURN(result);  END get_attr_value;  -- 在 xmldom 中对象的节点下增加子节点及值  FUNCTION create_son_node(p_doc xmldom.DOMDocument,p_node xmldom.DOMNode,p_node_name VARCHAR2,p_node_value VARCHAR2) RETURN xmldom.DOMNode IS    elem xmldom.DOMElement;          -- 声明Element对象    node xmldom.DOMNode;             -- 声明节点对象    text_node xmldom.DOMNode;        -- 声明节点对象    text xmldom.DOMText ;            -- 声明DOMText对象  BEGIN    elem := xmldom.createElement(p_doc,p_node_name);    node := xmldom.appendChild(p_node, xmldom.makeNode(elem));    text := xmldom.createTextNode(p_doc,p_node_value);    text_node := xmldom.appendChild(node,xmldom.makeNode(text));    RETURN(node);  END create_son_node;  -- 在 xmldom 中对象的节点下增加子节点  FUNCTION create_son_node(p_doc xmldom.DOMDocument,p_node xmldom.DOMNode,p_node_name VARCHAR2) RETURN xmldom.DOMNode IS    elem xmldom.DOMElement;      -- 声明Element对象    node xmldom.DOMNode;         -- 声明节点对象  BEGIN    elem := xmldom.createElement(p_doc,p_node_name);    node := xmldom.appendChild(p_node, xmldom.makeNode(elem));    RETURN(node);  END create_son_node;

   /*递归克隆节点*/  PROCEDURE clone_node_dg(p_destdoc  xmldom.DOMDocument,                          p_sourcenode xmldom.DOMNode,                          p_destnode   xmldom.DOMNode)  IS

    ndl xmldom.DOMNodeList;      -- 声明节点列表    len NUMBER;                  -- 个数    node xmldom.DOMNode;         -- 声明节点对象    v_nodename  VARCHAR2(300);    --节点名    v_nodeValue VARCHAR2(300);    --节点值    elem xmldom.DOMElement;       -- 声明Element对象    text_node xmldom.DOMNode;     -- 声明节点对象    text xmldom.DOMText ;         -- 声明DOMText对象  BEGIN    ndl := xmldom.getChildNodes(p_sourcenode);    len := xmldom.getLength(ndl);    FOR i IN 0..len-1 LOOP      v_nodeValue := xmldom.getNodeValue(xmldom.item(ndl, i));      IF v_nodeValue IS NOT NULL THEN        text := xmldom.createTextNode(p_destdoc,v_nodeValue);        text_node := xmldom.appendChild(p_destnode,xmldom.makeNode(text));      ELSE        v_nodename :=  xmldom.getNodeName(xmldom.item(ndl, i)) ;        elem := xmldom.createElement(p_destdoc,v_nodename);        node := xmldom.appendChild(p_destnode, xmldom.makeNode(elem));

        clone_node_dg(p_destdoc,xmldom.item(ndl, i),node);

      END IF;

    END LOOP;  END clone_node_dg;

  /*将一段xml字符串创建到指定的节点下*/  PROCEDURE import_node (    p_doc  xmldom.DOMDocument,           -- 声明xmldomc对象    p_parentnode  xmldom.DOMNode,        -- 声明节点对象(xml需要加在下面)    p_xml  VARCHAR2                      -- 输入xml字符串  ) IS

    elem xmldom.DOMElement;      -- 声明Element对象    node xmldom.DOMNode;         -- 声明节点对象    v_nodename  VARCHAR2(300);    --节点名

    insertpar xmlparser.parser;   -- 声明xmlparser对象    insertdoc xmldom.DOMDocument; -- 声明xmldomc对象    insertroot xmldom.DOMNode;    -- 声明根node对象    insertndl xmldom.DOMNodeList; -- 声明节点列表

  BEGIN

    insertpar := xmlparser.newParser;

    -- 把xml字符串装载进入xmldom对象    xmlparser.parseBuffer(insertpar,p_xml);    insertdoc := xmlparser.getDocument(insertpar);

    -- 先取根元素    insertndl := xmldom.getElementsByTagName(insertdoc,'*');    insertroot := xmldom.item(insertndl, 0);

    --创建一个父节点    v_nodename :=  xmldom.getNodeName(insertroot) ;    elem := xmldom.createElement(p_doc,v_nodename);    node := xmldom.appendChild(p_parentnode, xmldom.makeNode(elem));

    clone_node_dg(p_doc,insertroot,node);

    -- 释放资源    xmldom.freeDocument(insertdoc);    xmlparser.freeParser(insertpar);  END import_node;

  PROCEDURE get_node_xml(p_xml_in VARCHAR2,p_node_name VARCHAR2,p_xml_out OUT VARCHAR2)  IS    par xmlparser.parser;            -- 声明xmlparser对象    doc xmldom.DOMDocument;          -- 声明xmldomc对象    elem xmldom.DOMElement;          -- 声明Element对象    root xmldom.DOMNode;             -- 声明根node对象

    ndl xmldom.DOMNodeList;          -- 声明节点列表    node xmldom.DOMNode;             -- 声明节点对象    par_in xmlparser.parser;         -- 声明xmlparser对象    doc_in xmldom.DOMDocument;       -- 声明xmldomc对象

    ndl_in xmldom.DOMNodeList;       -- 声明节点列表    node_in xmldom.DOMNode;          -- 声明节点对象  BEGIN    -- 创建新xmlparser对象(IN)    par_in := xmlparser.newParser;    xmlparser.parseBuffer(par_in,p_xml_in);    doc_in := xmlparser.getDocument(par_in);    ndl :=  xmldom.getElementsByTagName(doc_in,p_node_name);    node_in:= xmldom.item(ndl, 0);

    -- 创建新xmlparser对象(out)    par := xmlparser.newParser;    xmlparser.parseBuffer(par,'<'||p_node_name||'></'||p_node_name||'>');    doc := xmlparser.getDocument(par);

    ndl :=  xmldom.getElementsByTagName(doc,p_node_name);    root:= xmldom.item(ndl, 0);

    clone_node_dg(doc,node_in,root);

    xmldom.writeToBuffer(doc,p_xml_out);    -- 释放资源    xmldom.freeDocument(doc);    xmldom.freeDocument(doc_in);    xmlparser.freeParser(par);    xmlparser.freeParser(par_in);  END get_node_xml;

  /*将一段xml字符串创建到指定的节点下*/  PROCEDURE import_node (    p_doc  xmldom.DOMDocument,           -- 声明xmldomc对象    p_parentnode  xmldom.DOMNode,        -- 声明节点对象(xml需要加在下面)    p_xml  CLOB                          -- 输入xml字符串    ) IS

    elem xmldom.DOMElement;      -- 声明Element对象    node xmldom.DOMNode;         -- 声明节点对象    v_nodename  VARCHAR2(300);    --节点名

    insertpar xmlparser.parser;   -- 声明xmlparser对象    insertdoc xmldom.DOMDocument; -- 声明xmldomc对象    insertroot xmldom.DOMNode;    -- 声明根node对象    insertndl xmldom.DOMNodeList; -- 声明节点列表

  BEGIN

    insertpar := xmlparser.newParser;

    -- 把xml字符串装载进入xmldom对象    --xmlparser.parseBuffer(insertpar,p_xml);    xmlparser.parseCLOB(insertpar,p_xml);    insertdoc := xmlparser.getDocument(insertpar);

    -- 先取根元素    insertndl := xmldom.getElementsByTagName(insertdoc,'*');    insertroot := xmldom.item(insertndl, 0);

        --创建一个父节点    v_nodename :=  xmldom.getNodeName(insertroot) ;    elem := xmldom.createElement(p_doc,v_nodename);    node := xmldom.appendChild(p_parentnode, xmldom.makeNode(elem));

    clone_node_dg(p_doc,insertroot,node);

    -- 释放资源    xmldom.freeDocument(insertdoc);    xmlparser.freeParser(insertpar);  END import_node;

  PROCEDURE get_node_xml(p_xml_in CLOB,p_node_name VARCHAR2,p_xml_out OUT CLOB)  IS    par xmlparser.parser;            -- 声明xmlparser对象    doc xmldom.DOMDocument;          -- 声明xmldomc对象    elem xmldom.DOMElement;          -- 声明Element对象    root xmldom.DOMNode;             -- 声明根node对象

    ndl xmldom.DOMNodeList;          -- 声明节点列表    node xmldom.DOMNode;             -- 声明节点对象    par_in xmlparser.parser;         -- 声明xmlparser对象    doc_in xmldom.DOMDocument;       -- 声明xmldomc对象

    ndl_in xmldom.DOMNodeList;       -- 声明节点列表    node_in xmldom.DOMNode;          -- 声明节点对象  BEGIN    -- 创建新xmlparser对象(IN)    par_in := xmlparser.newParser;    --xmlparser.parseBuffer(par_in,p_xml_in);    xmlparser.parseClob(par_in,p_xml_in);    doc_in := xmlparser.getDocument(par_in);    ndl :=  xmldom.getElementsByTagName(doc_in,p_node_name);    node_in:= xmldom.item(ndl, 0);

    -- 创建新xmlparser对象(out)    par := xmlparser.newParser;    xmlparser.parseBuffer(par,'<'||p_node_name||'></'||p_node_name||'>');    doc := xmlparser.getDocument(par);

    ndl :=  xmldom.getElementsByTagName(doc,p_node_name);    root:= xmldom.item(ndl, 0);

    clone_node_dg(doc,node_in,root);

    --xmldom.writeToBuffer(doc,p_xml_out);    dbms_lob.createtemporary(p_xml_out, TRUE, dbms_lob.SESSION);    xmldom.writeToClob(doc,p_xml_out);

    -- 释放资源    xmldom.freeDocument(doc);    xmldom.freeDocument(doc_in);    xmlparser.freeParser(par);    xmlparser.freeParser(par_in);

  END get_node_xml;END zte_fbp_xml_util_pkg;/