【问题标题】:error reading xml from the plsql procedure从 plsql 过程读取 xml 时出错
【发布时间】:2011-08-15 09:33:50
【问题描述】:

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

ORA-31020: 不允许该操作,原因: 不支持 ORA-06512:在“XDB.DBMS_XMLPARSER”,第 395 行 ORA-06512:在“SYS.DOMSAMPLE”,第 75 行 ORA-06512: 在第 2 行

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

谁能帮我解决这个问题。或者建议一种在plsql中读取xml的简单方法。

【问题讨论】:

    标签: xml oracle plsql ora-06512


    【解决方案1】:

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

    我无法重现您的错误消息,但我只尝试了几件事。也许您错误地调用了 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 的更简单方法,there's one in a question I answered earlier。我不知道这是否会对你有所帮助,因为我对你想要达到的目标知之甚少。

    最后,请不要在 SYS 架构中创建对象。

    编辑:在您的评论中,您提到您使用的是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 目录:

    SQL> 创建或替换目录 ora_dir 为 '/home/luke/ora_dir'; 已创建目录。

    我在这里使用 Linux。如果您使用的是 Windows,请随意反转斜线的方向。

    在我们继续之前,让我们快速浏览一下我们将读入的 XML 文件:

    SQL> 主机猫 /home/luke/ora_dir/example.xml

    在 SQL*Plus 中,host 将行的其余部分发送到 shell,或者在 Windows 上为 cmd.exe。在 Windows 上,您还可以使用 type 而不是 cat

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

    SQL> 设置服务器输出 SQL> 声明 2 p dbms_xmlparser.parser; 3d dbms_xmldom.domdocument; 4 e dbms_xmldom.dom 元素; 5 开始 6 p := dbms_xmlparser.newParser; 7 dbms_xmlparser.setBaseDir(p, 'ORA_DIR'); 8 dbms_xmlparser.parse(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 / 标签名称是根 PL/SQL 过程成功完成。 SQL>

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

    编辑 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,正如三个 cmets 中的最后一个所建议的那样。

    引用a previous answer of mine on a similar question

    在 XML DOM 中,元素没有任何“价值”可言。元素节点包含 Text 节点作为子节点,正是这些节点包含您想要的值。

    所以,换行试试

          nodeval := xmldom.getNodeValue(n);
    

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

    【讨论】:

    • 在上面的 sn-p 中,你写的,我用 dbms_xmlparser.parse(p,'c:/Desktop/family.xml') 替换了 dbms_xmlparser.parseBuffer,它给了我一个错误资源句柄或路径名“c:/Desktop/famil.xml”无效。 xml 文件是 -SarahBob乔安妮 吉姆
    • @Navin:您的 XML 文档看起来不错。有关使用 dbms_xmlparser.parse 的示例,请参阅我的编辑。
    • 是的,对于上面的 xml,我还有一个问题,对于上面的代码,我又添加了一个过程来打印所有节点的名称和值:我得到的值一个节点什么都没有(我的意思是 null).. 相应的代码在下一条评论中
    • @Navin,以及任何批准您对我的回答进行编辑的人:请不要在以后将您的代码添加到我的回答中。我没有写你的代码,所以除非我把它放在那里,否则它不应该出现在我的答案中。您的编辑根本没有遵循 SO“如何编辑”指南,我对您这样做对我的回答不满意。以后,请编辑您的问题,或提出单独的后续问题。
    猜你喜欢
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    相关资源
    最近更新 更多