使用 PL/SQL 的 DOM API 解析 XML 文档

这个程序示范了使用 PL/SQL 的 DOM API 解析 XML 文档,
-- 使用了 SYS.XMLDOM 和 SYS.XMLPARSER包
-- 程序解析了输入的 XML 文件,打印文档所有元素和元素的属性

connect scott/tiger;

set serveroutput on;
create or replace procedure domsample(dir varchar2, inpfile varchar2,
                                      errfile varchar2) is
-- 参数说明:
-- dir      基本目录,如 'd:\xml\plsql'
-- inpfile  输入文件名,不含路径,如 'student.xml'
-- errfile  错误日志文件,保存解析错误信息, 如 'err.log'

p xmlparser.parser;
doc xmldom.DOMDocument;

-- 打印文档中的元素及元素的文本信息
procedure printElements(doc xmldom.DOMDocument) is
  nl xmldom.DOMNodeList;
  len number;
  n xmldom.DOMNode;

begin
   -- 获取所有元素
   nl := xmldom.getElementsByTagName(doc, '*'); -- * 表示所有元素,包括根元素
   len := xmldom.getLength(nl);

   -- 遍历所有元素
   for i in 0..len-1 loop
      n := xmldom.item(nl, i);
      dbms_output.put_line(xmldom.getNodeName(n) || ':'
                           || xmldom.getNodeValue(xmldom.getFirstChild(n)));
   end loop;

   dbms_output.put_line('');  -- 打印空行
end printElements;

-- 打印文档中每个元素的属性
procedure printElementAttributes(doc xmldom.DOMDocument) is
  nl xmldom.DOMNodeList;
  len1 number;
  len2 number;
  n xmldom.DOMNode;
  e xmldom.DOMElement;
  nnm xmldom.DOMNamedNodeMap;
  attrname varchar2(100);
  attrval varchar2(100);

begin

   -- 获取所有元素
   nl := xmldom.getElementsByTagName(doc, '*'); -- * 表示所有元素,包括根元素
   len1 := xmldom.getLength(nl);

   -- 遍历所有元素
   for j in 0..len1-1 loop
      n := xmldom.item(nl, j);
      e := xmldom.makeElement(n);
      dbms_output.put_line(xmldom.getTagName(e) || '!');
     
      -- 获取元素的所有属性
      nnm := xmldom.getAttributes(n);

     if (xmldom.isNull(nnm) = FALSE) then  -- 如果有属性
        len2 := xmldom.getLength(nnm);

        -- 遍历所有属性
        for i in 0..len2-1 loop
           n := xmldom.item(nnm, i);
           attrname := xmldom.getNodeName(n);
           attrval := xmldom.getNodeValue(n);
           dbms_output.put_line(' ' || attrname || ' = ' || attrval);
        end loop;
        dbms_output.put_line('');
     end if;
   end loop;

end printElementAttributes;

begin
-- 新建解析器实例
   p := xmlparser.newParser;

-- 设置解析器特性
   xmlparser.setValidationMode(p, TRUE); -- 是否使用文档指定的DTD验证文档合法性
   xmlparser.setErrorLog(p, dir || '\' || errfile); -- 设置错误日志文件
   xmlparser.setBaseDir(p, dir);   -- 设置基本目录

-- 解析输入的xml文件
   xmlparser.parse(p, dir || '\' || inpfile);

-- 获取解析后的文档对象
   doc := xmlparser.getDocument(p);

-- 释放解析器实例
   xmlparser.freeParser(p);

-- 打印文档元素
   dbms_output.put('文档元素: ');
   printElements(doc);

-- 打印文档元素属性
   dbms_output.put_line('每个元素的属性: ');
   printElementAttributes(doc);

-- 释放文档对象
   xmldom.freeDocument(doc);

-- 处理异常
exception
  when xmldom.INDEX_SIZE_ERR then
     raise_application_error(-20120, 'Index Size error');
  when xmldom.DOMSTRING_SIZE_ERR then
     raise_application_error(-20120, 'String Size error');
  when xmldom.HIERARCHY_REQUEST_ERR then
     raise_application_error(-20120, 'Hierarchy request error');
  when xmldom.WRONG_DOCUMENT_ERR then
     raise_application_error(-20120, 'Wrong doc error');
  when xmldom.INVALID_CHARACTER_ERR then
     raise_application_error(-20120, 'Invalid Char error');
  when xmldom.NO_DATA_ALLOWED_ERR then
     raise_application_error(-20120, 'Nod data allowed error');
  when xmldom.NO_MODIFICATION_ALLOWED_ERR then
     raise_application_error(-20120, 'No mod allowed error');
  when xmldom.NOT_FOUND_ERR then
     raise_application_error(-20120, 'Not found error');
  when xmldom.NOT_SUPPORTED_ERR then
     raise_application_error(-20120, 'Not supported error');
  when xmldom.INUSE_ATTRIBUTE_ERR then
     raise_application_error(-20120, 'In use attr error');
end domsample;
/
show errors;

/*
-- 可以使用以下语句进行调用
execute domsample('d:\xml\plsql', 'student.xml', 'err.log');
*/

你可能感兴趣的:(sql,xml,J#)