我在网上搜到一个Oracle存储过程解析XML文件的例子,据说这是为初学者准备的.相应的存储过程如下:
    
    create or replace procedure domsample(dir varchar2, inpfile varchar2,
                                      errfile varchar2) is
-- 参数说明:
-- dir      基本目录,如 'd:\xml\plsql'
-- inpfile  输入文件名,不含路径,如 'people.xml'
-- errfile  错误日志文件,保存解析错误信息, 如 'err.log'p xmlparser.parser;
doc xmldom.DOMDocument;procedure xmlinserttable(doc xmldom.DOMDocument) is
  nl xmldom.DOMNodeList;
  len number;
  len2 number;
  n xmldom.DOMNode;
  nnm xmldom.DOMNamedNodeMap;
  attrname varchar2(100);
  attrval varchar2(100);
  strSQL varchar2(20000);
  attn xmldom.DOMNode;
  nl2 xmldom.DOMNodeList;
begin
nl := xmldom.getElementsByTagName(doc, 'PERSON');  -- 读取 PERSON 元素
len := xmldom.getLength(nl);
-- 遍历元素
for i in 0..len-1 loop
   strSQL := 'INSERT INTO PEOPLE VALUES (';  -- 构造动态 SQL 语句
   n := xmldom.item(nl, i);
   if xmldom.getNodeName(n)='PERSON' then
      nnm := xmldom.getAttributes(n);  -- 读取 ID 属性
      attn := xmldom.item(nnm, 0);
      strSQL := strSQL || ''''  || xmldom.getNodeValue(attn) || '''';
   end if;
   -- 读取 PERSON 的子节点
   nl2 := xmldom.getChildNodes(n);
   len2 := xmldom.getLength(nl2);
   -- 处理 NAME, ADDRESS, ... 等节点
   for j in 0..len2-1 loop
      n := xmldom.item(nl2, j);
      strSQL := strSQL || ', '''  || xmldom.getNodeValue(xmldom.getFirstChild(n)) || '''';
   end loop;
   strSQL := strSQL || ')';   -- 完成 动态 SQL 语句的构造
   -- 执行插入记录的 SQL 语句
   execute immediate(strSQL);  -- 执行动态 SQL
end loop;
commit;  -- 提交插入
end xmlinserttable;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_line('插入数据中...');
   xmlinserttable(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;
在d:\xml\plsql下已建立People.xml和People.dtd文件.内容如下:
People.xml文件内容如下:
  <?xml version="1.0"?>
<!DOCTYPE PEOPLE SYSTEM "people.dtd">
<PEOPLE>
<PERSON ID="E01">
  <NAME>Tony Blair</NAME>
  <ADDRESS>10 Downing Street, London, UK</ADDRESS>
  <TEL>(061) 98765</TEL>
  <FAX>(061) 98768</FAX>
  <EMAIL>[email protected]</EMAIL>
</PERSON>
<PERSON ID="E02">
  <NAME>Bill Clinton</NAME>
  <ADDRESS>White House, USA</ADDRESS>
  <TEL>(001) 6400 98765</TEL>
  <FAX>(001) 6400 98769</FAX>
  <EMAIL>[email protected]</EMAIL>
</PERSON>
<PERSON ID="E03">
  <NAME>Tom Cruise</NAME>
  <ADDRESS>57 Jumbo Street, New York, USA</ADDRESS>
  <TEL>(001) 4500 67859</TEL>
  <FAX>(001) 4500 67895</FAX>
  <EMAIL>[email protected]</EMAIL>
</PERSON>
<PERSON ID="E04">
  <NAME>Linda Goodman</NAME>
  <ADDRESS>78 Crax Lane, London, UK</ADDRESS>
  <TEL>(061) 54 56789</TEL>
  <FAX>(061) 54 56772</FAX>
  <EMAIL>[email protected]</EMAIL>
</PERSON>
</PEOPLE>People.dtd文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT ADDRESS (#PCDATA)>
<!ELEMENT EMAIL (#PCDATA)>
<!ELEMENT FAX (#PCDATA)>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT PEOPLE (PERSON+)>
<!ELEMENT PERSON (NAME, ADDRESS, TEL, FAX, EMAIL)>
<!ATTLIST PERSON
ID CDATA #REQUIRED
>
<!ELEMENT TEL (#PCDATA)>
我在命令窗口中通过以下命令运行此存储过程的结果如下:
SQL> exec domsample('d:\xml\plsql','people.xml','err.log');begin domsample('d:\xml\plsql','people.xml','err.log'); end;ORA-31020: 不允许执行此操作, 原因: Not supported
ORA-06512: 在 "XDB.DBMS_XMLPARSER", line 395
ORA-06512: 在 "HXY.DOMSAMPLE", line 55
ORA-06512: 在 line 1造成此错误的原因就是上面红色标识出的那行语句.请教有此经验的朋友告知这是什么原因?谢谢.

解决方案 »

  1.   

    好长,没仔细看,有创建目录访问部分吗:
    如果没有加上试试:SQL> CREATE DIRECTORY dir_test AS 'd:\xml\plsql'; 
    SQL> GRANT WRITE ,READ ON DIRECTORY dir_test TO yourUser; 
      

  2.   

    不是啊,我在'd:\xml\plsql' 下已经建立了people.xml及people.dtd文件。还是不行……,望高人指点,随即散分~~~~~~~~~~
      

  3.   

    CREATE DIRECTORY和GRANT了没?访问操作系统的文件目录是需要先做这些的。
      

  4.   

    还是不行的。
    执行到xmlparser.setErrorLog(p, dir || '\' || errfile); -- 设置错误日志文件
    时出错。