从PLSQL过程读取XML时出错



我正在尝试使用xmlparser包从plsql过程中读取xml,我得到此错误

<>之前ORA-31020:不允许操作,原因:不支持ORA-06512:在"XDB"。DBMS_XMLPARSER",第395行ORA-06512: at"SYS."DOMSAMPLE",第75行ORA-06512:在第2行之前

DOMSAMPLE是我的过程名,第75行没有语句,下一行包含p := xmlparser.newParser

有人能帮我解决这个问题吗?或建议一个简单的方法来读取xml在plsql

关于你实际在做什么,你提供的细节太少了,所以恐怕我只能猜测了。

我无法重现您的错误信息,但我只尝试了一些事情。也许您错误地调用了Oracle XML api ?也许您试图解析的XML文档有些奇怪?恐怕我不知道,因为你没有给我们你的DOMSAMPLE过程的来源,也没有给我们你试图解析的XML文档。

我不能相信你的程序的第75行是一个空行。这是过程的第75行,还是包含过程的文件的第75行?

这里有一个使用DBMS_XMLPARSERDBMS_XMLDOM的例子。它只读出给定XML字符串的根元素的名称:

SET SERVEROUTPUT ON;
DECLARE
   p    dbms_xmlparser.parser;
   d    dbms_xmldom.domdocument;
   e    dbms_xmldom.domelement;
BEGIN
   p := dbms_xmlparser.newParser;
   dbms_xmlparser.parseBuffer(p, '<thisIsATest />');
   d := dbms_xmlparser.getDocument(p);
   e := dbms_xmldom.getDocumentElement(d);
   dbms_output.put_line('Tag name is ' || dbms_xmldom.getTagName(e));
END;
/

当我运行这个时,它给了我输出Tag name is thisIsATest

至于阅读XML的更简单的方法,在我之前回答的一个问题中有一个。我不知道这是否对你有帮助,因为我对你想要达到的目标知之甚少。

最后,请不要在SYS模式下创建对象。

EDIT:在你的评论中,你提到你正在使用dbms_xmlparser.parse而不是dbms_xmlparser.parseBuffer。我玩了dbms_xmlparser.parse,并在最终找到有效的东西之前多次遇到相同的"无效资源句柄或路径名"错误。下面是我设法得到的工作;也许有比这更好的解决方案。

在你可以用Oracle做任何文件I/O之前,这似乎包括使用dbms_xmlparser.parse,你必须首先创建一个Oracle '目录'。Oracle中的目录对应于文件系统中的目录。注意,这是运行Oracle数据库的机器上的文件系统。如果XML文件不在同一个文件系统上(例如Oracle数据库在服务器上,而你的XML文件在你的开发PC上),你将无法使用dbms_xmlparser.parse,除非你先将这个文件传输到数据库服务器的文件系统上的目录。

我将首先创建一个Oracle目录,该目录与我的文件系统上的目录相对应:

<>之前创建或替换目录ora_dir为/home/luke/ora_dir;创建目录。之前

我在这里使用Linux。如果你使用的是Windows操作系统,可以随意反转斜杠的方向。

在进一步讨论之前,让我们快速查看一下将要读取的XML文件:

<>之前SQL> host cat/home/luke/ora_dir/example.xml& lt; ?XML版本="1.0" ?>根> & lt;& lt;孩子/>& lt;/根>之前

在SQL*Plus中,host将剩余的行发送给shell,或者在Windows中cmd.exe。在Windows上,你也可以使用type而不是cat

最后,这里是读取XML文件的PL/SQL块:

<>之前SQL> set serveroutput onSQL>声明2 p dbms_xmlparser.parser;3 d dbms_xmldom.domdocument;dbms_xmldom.domelement;5开始6 p:= dbms_xmlparser.newParser;7 dbms_xmlparser。setBaseDir (p"ORA_DIR");8 dbms_xmlparser。解析(p"example.xml");9 d:= dbms_xmlparser.getDocument(p);10 e:= dbms_xmldom.getDocumentElement(d);11 dbms_output。put_line('标签名称是' || dbms_xmldom.getTagName(e));12结束;13/标签名称为rootPL/SQL过程成功完成。SQL>之前

该块与上面的块之间的唯一区别是称为dbms_xmlparser.parseBuffer的行已被替换为两行。这两行中的第一行调用dbms_xmlparser.setBaseDir,为解析器设置一个基本目录,第二行调用dbms_xmlparser.parse,使用相对于该目录的文件名。

EDIT 2:你的代码,不像你希望的那样工作,你编辑成我的答案,如下所示:

create or replace procedure printElements(doc xmldom.DOMDocument) is
nl xmldom.DOMNodeList;
len number;
n xmldom.DOMNode;
e xmldom.DOMElement;
nodeval varchar2(100);
begin
   -- get all elements
   nl := xmldom.getElementsByTagName(doc, '*');
   len := xmldom.getLength(nl);   
   -- loop through elements
   for i in 0..len-1 loop
      n := xmldom.item(nl, i);
      e := xmldom.makeElement(n => n);
      dbms_output.put(xmldom.getNodeName(n) || ' ');
      nodeval := xmldom.getNodeValue(n);
      -- here nodeval i am getting as null, what mistake am doing?
      dbms_output.put_line('  Value: '|| nodeval );
   end loop;
   dbms_output.put_line('');
end printElements;

这显然是将所有值返回为null,正如三个注释中的最后一个所建议的那样。

引用我之前对类似问题的回答:

在XML DOM中,元素没有任何"值"可言。元素节点包含文本节点作为子节点,这些节点包含您想要的值。

那么,试着替换

      nodeval := xmldom.getNodeValue(n);

      nodeval := xmldom.getNodeValue(xmldom.getFirstChild(n));

相关内容

  • 没有找到相关文章

最新更新