Create_XML

CREATE OR REPLACE PACKAGE create_xml IS

-- Declare XML types
   type ry_path is record (
                           full_path varchar2(4000),
                           node_name varchar2(512),
                           node_path varchar2(4000),
                           attb_name varchar2(512),
                           attb_path varchar2(4000)
                          );

-- Constants
   c_path_sep           CONSTANT varchar2(1) := '/';
   c_attb_sep           CONSTANT varchar2(1) := '@';
   c_function_sep_start CONSTANT varchar2(1) := '[';
   c_function_sep_end   CONSTANT varchar2(1) := ']';

-- Initialize XML
procedure init_xml(
                   p_domdoc     in out dbms_xmldom.DOMDocument,
                   p_index_id   in     varchar2,
                   p_node_name  in     varchar2,
                   p_text_value in     varchar2
                  );

-- Add and write node to XML DOMDocument
procedure create_node(
                      p_domdoc     in out dbms_xmldom.DOMDocument,
                      p_index_id   in     varchar2,
                      p_node_name  in     varchar2,
                      p_text_value in     varchar2
                     );

-- Add attribute to XML DOMDocument
procedure add_attr(
                   p_index_id   in varchar2,
                   p_attr_name  in varchar2,
                   p_text_value in varchar2
                  );

-- Add node or attribute to XML DOMDocument (path notation)
procedure add_element(
                      p_path   in     varchar2,
                      p_value  in     varchar2,
                      p_domdoc in out dbms_xmldom.DOMDocument
                     );

-- Tokenize Path expresion
function tokenize_path(
                       p_path               in varchar2,
                       p_path_sep           in varchar2 default c_path_sep,
                       p_attb_sep           in varchar2 default c_attb_sep,
                       p_function_sep_start in varchar2 default c_function_sep_start,
                       p_function_sep_end   in varchar2 default c_function_sep_end
                      ) return ry_path;

-- Get parent in Path expresion
function get_parent(
                    p_path     in varchar2
                   ) return varchar2;

-- Write XML DOM to Blob
procedure write_xmldom2blob (
                             p_domdoc in     dbms_xmldom.DOMDocument,
                             p_csid   in     number,
                             p_blob   in out nocopy blob
                            );

-- Create an example
procedure xml_example;

END create_xml;

CREATE OR REPLACE PACKAGE BODY create_xml AS

-- Private types

   -- Internal XML types
   type ry_xmlelement is record (
                                 p_parent       dbms_xmldom.DOMNode,
                                 p_element_name varchar2(512),
                                 p_element      dbms_xmldom.DOMElement,
                                 p_node         dbms_xmldom.DOMNode,
                                 p_text_value   varchar2(32767),
                                 p_text         dbms_xmldom.DOMText,
                                 p_textnode     dbms_xmldom.DOMNode
                                );
   type ty_xmlelement is table of ry_xmlelement index by varchar2(32767);

   -- Internal variables
   tb_xmlelements ty_xmlelement;

-- Private functions and procedures

-- Add node to ty_xmlelement
procedure add_node(
                   p_index_id   in varchar2,
                   p_node_name  in varchar2,
                   p_text_value in varchar2
                  )
is
begin
 
   -- Add node
   tb_xmlelements(p_index_id).p_parent       := tb_xmlelements(get_parent(p_index_id)).p_node;
   tb_xmlelements(p_index_id).p_element_name := p_node_name;
   tb_xmlelements(p_index_id).p_text_value   := p_text_value;
    
end add_node;
 
-- Write node to XML DOMDocument
procedure write_node(
                     p_domdoc   in out dbms_xmldom.DOMDocument,
                     p_index_id in     varchar2
                    )
is
begin
    
   -- Write node
   tb_xmlelements(p_index_id).p_element  := dbms_xmldom.createElement(p_domdoc, tb_xmlelements(p_index_id).p_element_name);
   tb_xmlelements(p_index_id).p_node     := dbms_xmldom.appendChild(tb_xmlelements(p_index_id).p_parent,dbms_xmldom.makeNode(tb_xmlelements(p_index_id).p_element));
   tb_xmlelements(p_index_id).p_text     := dbms_xmldom.createTextNode(p_domdoc, tb_xmlelements(p_index_id).p_text_value);
   tb_xmlelements(p_index_id).p_textnode := dbms_xmldom.appendChild(tb_xmlelements(p_index_id).p_node,dbms_xmldom.makeNode(tb_xmlelements(p_index_id).p_text));
 
end write_node;

-- Public functions and procedures

-- Initialize XML
procedure init_xml(
                   p_domdoc     in out dbms_xmldom.DOMDocument,
                   p_index_id   in     varchar2,
                   p_node_name  in     varchar2,
                   p_text_value in     varchar2
                  )
is
   l_root_node dbms_xmldom.DOMNode;
begin
 
   -- Init internal table
   tb_xmlelements.delete;
   
   -- Create a root node
   l_root_node := dbms_xmldom.makeNode(p_domdoc);
 
   tb_xmlelements(p_index_id).p_parent       := l_root_node;
   tb_xmlelements(p_index_id).p_element_name := p_node_name;
   tb_xmlelements(p_index_id).p_text_value   := p_text_value;

   write_node(p_domdoc, p_index_id);

end init_xml;

-- Add node to XML DOMDocument
procedure create_node(
                      p_domdoc     in out dbms_xmldom.DOMDocument,
                      p_index_id   in     varchar2,
                      p_node_name  in     varchar2,
                      p_text_value in     varchar2
                     )
is
begin
 
   -- Add node
   add_node(p_index_id, p_node_name, p_text_value);
    
   -- Write node
   write_node(p_domdoc, p_index_id);
    
end create_node;

-- Add attribute to XML DOMDocument
procedure add_attr(
                   p_index_id   in varchar2,
                   p_attr_name  in varchar2,
                   p_text_value in varchar2
                  )
is
begin
 
   -- Add attribute
   dbms_xmldom.setAttribute(
       tb_xmlelements(p_index_id).p_element,
       p_attr_name,
       p_text_value);
    
end add_attr;

-- Add node or attribute to XML DOMDocument (path notation)
procedure add_element(
                      p_path   in     varchar2,
                      p_value  in     varchar2,
                      p_domdoc in out dbms_xmldom.DOMDocument
                     )
is
   reg_path ry_path;
begin
 
   -- Read p_path
   reg_path := tokenize_path(p_path => p_path);
   
   -- Switch node / attribute
   if reg_path.attb_name is not null then
      add_attr(
               p_index_id   => reg_path.attb_path,
               p_attr_name  => reg_path.attb_name,
               p_text_value => p_value
              );
   else
      create_node(
                  p_domdoc     => p_domdoc,
                  p_index_id   => reg_path.full_path,
                  p_node_name  => reg_path.node_name,
                  p_text_value => p_value
                 );
   end if;
    
end add_element;

-- Tokenize Path expresion
function tokenize_path(
                       p_path               in varchar2,
                       p_path_sep           in varchar2 default c_path_sep,
                       p_attb_sep           in varchar2 default c_attb_sep,
                       p_function_sep_start in varchar2 default c_function_sep_start,
                       p_function_sep_end   in varchar2 default c_function_sep_end
                      ) return ry_path
is
   v_path_sep           varchar2(1);
   v_attb_sep           varchar2(1);
   v_function_sep_start varchar2(1);
   v_function_sep_end   varchar2(1);
   
   reg_path             ry_path;
begin

   -- Init variables
   v_path_sep           := nvl(p_path_sep, c_path_sep);
   v_attb_sep           := nvl(p_attb_sep, c_attb_sep);
   v_function_sep_start := nvl(p_function_sep_start, c_function_sep_start);
   v_function_sep_end   := nvl(p_function_sep_end, c_function_sep_end);

   reg_path.full_path   := p_path;
    
   -- Remove end path_sep
   if substr(reg_path.full_path, -1, 1) = v_path_sep then
       reg_path.full_path := substr(reg_path.full_path, 1, length(reg_path.full_path)-1);
   end if;
    
   -- Check for attrib
   if instr(reg_path.full_path, v_path_sep||v_attb_sep, 1, 2) > 1 then
       raise_application_error(-20001, 'Only one '||v_attb_sep||' is allowed.', true);
   elsif instr(reg_path.full_path, v_path_sep||v_attb_sep) > 0 then
       reg_path.attb_name := substr(reg_path.full_path, instr(reg_path.full_path, v_path_sep||v_attb_sep)+2);
       reg_path.attb_path := substr(reg_path.full_path, 1, instr(reg_path.full_path, v_path_sep||v_attb_sep, -1)-1);

       reg_path.node_path := substr(reg_path.full_path, 1, instr(reg_path.full_path, v_path_sep||v_attb_sep, -1)-1);
   else
       reg_path.node_path := reg_path.full_path;
   end if;

   -- Tokenize node
   reg_path.node_name := regexp_substr(
                             regexp_substr(reg_path.node_path, '[^'||v_path_sep||']+$'),
                             '[^'||v_function_sep_start||'|'||v_path_sep||v_attb_sep||']+');
   
   reg_path.node_path := substr(reg_path.node_path, 1, instr(reg_path.node_path, v_path_sep, -1)-1);
   
   -- End
   return reg_path;

end tokenize_path;

-- Get parent in Path expresion
function get_parent(
                    p_path     in varchar2
                   ) return varchar2
is
   reg_path ry_path;
begin

   -- Extract parent
   reg_path := tokenize_path(p_path => p_path);
   
   return reg_path.node_path;
   
end get_parent;

-- Write XML DOM to Blob
procedure write_xmldom2blob (
                             p_domdoc in     dbms_xmldom.DOMDocument,
                             p_csid   in     number,
                             p_blob   in out nocopy blob
                            )
is
    cl_xml       clob;
    dest_offset  integer := 1;
    src_offset   integer := 1;
    lang_context integer := 0;
    warning      integer;
begin
    
    -- Init variables
    dbms_lob.createtemporary(lob_loc => cl_xml, cache => false, dur => dbms_lob.call);
    
    -- Write XML DOM to Clob
    dbms_xmldom.writeToClob(doc => p_domdoc, cl => cl_xml);

    -- Convert Clob to Blob
    dbms_lob.convertToBlob(
        dest_lob     => p_blob, 
        src_clob     => cl_xml, 
        amount       => dbms_lob.lobmaxsize, 
        dest_offset  => dest_offset, 
        src_offset   => src_offset, 
        blob_csid    => p_csid, 
        lang_context => lang_context, 
        warning      => warning);
    
    -- Free resources
    dbms_lob.freetemporary(lob_loc => cl_xml);

end write_xmldom2blob;

-- Create an example
procedure xml_example
IS
  l_domdoc dbms_xmldom.DOMDocument;
  v_buffer varchar2(32767);
begin

   -- Create an empty XML document
   l_domdoc := dbms_xmldom.newDomDocument;

   -- Set version
   dbms_xmldom.setVersion(l_domdoc, '1.0" encoding="ISO-8859-1');
   --dbms_xmldom.setVersion(l_domdoc, '1.0');
   --dbms_xmldom.setCharset(l_domdoc, 'ISO-8859-1');

   -- Init XML
   create_xml.init_xml(l_domdoc, '/root', 'root', null);

   -- Add attributes to root node
   create_xml.add_element('/root/@RootAttr01', 'Root Atribute 01', l_domdoc);
   create_xml.add_element('/root/@RootAttr02', 'Root Atribute 02', l_domdoc);

   -- Create a new node with text and attributes
   create_xml.add_element('/root/node[1]', 'Node 01 text', l_domdoc);
   create_xml.add_element('/root/node[1]/@Attr01', 'Atribute 01', l_domdoc);
   create_xml.add_element('/root/node[1]/@Attr02', 'Atribute 02', l_domdoc);

   -- Create a additional node with text
   create_xml.add_element('/root/node[2]', '', l_domdoc);

   -- Create a additional node paretn with child nodes
   create_xml.add_element('/root/node_parent', '', l_domdoc);
   create_xml.add_element('/root/node_parent/@AttrNew01', 'text attr new 01', l_domdoc);

   create_xml.add_element('/root/node_parent/node_child[1]', 'Node Child aáa text 01', l_domdoc);
   create_xml.add_element('/root/node_parent/node_child[2]', 'Node Child text 02', l_domdoc);
   create_xml.add_element('/root/node_parent/node_child[3]', 'Node Child text 03', l_domdoc);

   -- Add child to /root/node02
   create_xml.add_element('/root/node[2]/node_child', 'Node 02 Child', l_domdoc);

   -- Result
   dbms_xmldom.writeToBuffer(l_domdoc, v_buffer, 'ISO-8859-1');

   $if not dbms_db_version.ver_le_10_2 $then
   select xmlserialize(DOCUMENT xmltype(v_buffer) AS varchar2(4000) INDENT) into v_buffer from dual;
   $end

   dbms_output.put_line(v_buffer);
   dbms_xmldom.freeDocument(l_domdoc);

end xml_example;

END create_xml;

El paquete cuenta con un procedimiento de ejemplo:

begin
    create_xml.xml_example;
end;

Resultado:

<?xml version="1.0" encoding="ISO-8859-1"?>
<root RootAttr01="Root Atribute 01" RootAttr02="Root Atribute 02">
  <node Attr01="Atribute 01" Attr02="Atribute 02">Node 01 text</node>
  <node>
    <node>Node 02 Child</node>
  </node>
  <node AttrNew01="text attr new 01">
    <node>Node Child aáa text 01</node>
    <node Attr="Node Child 02 Attribute">Node Child text 02</node>
    <node>Node Child text 03</node>
  </node>
</root>
Anuncio publicitario

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.