我正在尝试使用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
。
关于你实际在做什么,你提供的细节太少了,所以恐怕我只能猜测了。
我无法重现您的错误信息,但我只尝试了一些事情。也许您错误地调用了Oracle XML api ?也许您试图解析的XML文档有些奇怪?恐怕我不知道,因为你没有给我们你的DOMSAMPLE
过程的来源,也没有给我们你试图解析的XML文档。
我不能相信你的程序的第75行是一个空行。这是过程的第75行,还是包含过程的文件的第75行?
这里有一个使用DBMS_XMLPARSER
和DBMS_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));