0

I am trying to read a xml from plsql procedure using the xmlparser package, i am getting this error

ORA-31020: The operation is not allowed, Reason: Not supported
ORA-06512: at "XDB.DBMS_XMLPARSER", line 395
ORA-06512: at "SYS.DOMSAMPLE", line 75
ORA-06512: at line 2

DOMSAMPLE is my procedure name, and no statements are there at line number 75, and next line contains p := xmlparser.newParser.

Can somebody please help me in resolving this problem. Or suggest a simple way to read xml in plsql.

OMG Ponies
  • 325,700
  • 82
  • 523
  • 502
Navin
  • 411
  • 3
  • 9
  • 17

1 Answers1

0

You have provided scant few details about what you are actually doing, so I'm afraid I can only guess.

I cannot reproduce the error message you have, but I have only tried a few things. Perhaps you're calling the Oracle XML APIs incorrectly? Perhaps there's something odd about the XML document you're attempting to parse? I'm afraid I have no idea, since you haven't given us the source of your DOMSAMPLE procedure nor the XML document you're attempting to parse.

I cannot believe line 75 of your procedure is a blank line. Is this line 75 of the procedure, or line 75 of the file that contains the procedure?

Here's an example using DBMS_XMLPARSER and DBMS_XMLDOM. It merely reads out the name of the root element of the XML string given:

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;
/

When I run this it gives me the output Tag name is thisIsATest.

As for simpler ways to read XML, there's one in a question I answered earlier. I don't know whether that will help you, because I know very little about what you're trying to achieve.

Finally, please don't create objects in the SYS schema.

EDIT: in your comment, you mention that you're using dbms_xmlparser.parse instead of dbms_xmlparser.parseBuffer. I had a play with dbms_xmlparser.parse and hit the same 'invalid resource handle or path name' error several times before finally finding something that worked. Below is what I managed to get working; there may well be a better solution to what you want than this.

Before you can do any file I/O with Oracle, and that appears to include using dbms_xmlparser.parse, you must first create an Oracle 'directory'. Directories in Oracle correspond to directories on the filesystem. Note that this is the filesystem on the machine on which the Oracle database runs. If the XML file isn't on the same filesystem (e.g. the Oracle database is on a server and your XML file is on your development PC), you won't be able to use dbms_xmlparser.parse, unless you first transfer this file to a directory on the database server's filesystem.

I'll start by creating a Oracle directory corresponding to a directory on my filesystem:

SQL> create or replace directory ora_dir as '/home/luke/ora_dir';

Directory created.

I'm using Linux here. If you're using Windows, feel free to reverse the direction of the slashes.

Before we go any further, let's take a quick look at the XML file we'll read in:

SQL> host cat /home/luke/ora_dir/example.xml
<?xml version="1.0" ?>
<root>
  <child />
</root>

In SQL*Plus, host sends the rest of the line to the shell, or cmd.exe on Windows. On Windows you'd also use type instead of cat.

Finally, here's a PL/SQL block that reads this XML file:

SQL> set serveroutput on
SQL> DECLARE
  2     p    dbms_xmlparser.parser;
  3     d    dbms_xmldom.domdocument;
  4     e    dbms_xmldom.domelement;
  5  BEGIN
  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('Tag name is ' || dbms_xmldom.getTagName(e));
 12  END;
 13  /
Tag name is root

PL/SQL procedure successfully completed.

SQL>

The only difference between this block and the one further up is that the line that called dbms_xmlparser.parseBuffer has been replaced with two lines. The first of these two lines calls dbms_xmlparser.setBaseDir to set a base directory for the parser, and the second calls dbms_xmlparser.parse using a filename relative to this directory.

EDIT 2: Your code, which wasn't working quite as you had hoped, and which you edited into my answer, is as follows:

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;

This apparently was returning all the values as null, as suggested by the last of the three comments.

To quote a previous answer of mine on a similar question:

In XML DOM, elements don't have any 'value' to speak of. Element nodes contain Text nodes as children, and it is these nodes that contain the values you want.

So, try replacing the line

      nodeval := xmldom.getNodeValue(n);

with

      nodeval := xmldom.getNodeValue(xmldom.getFirstChild(n));
Community
  • 1
  • 1
Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • in the above snippet, what you have wrote, i am replacing the dbms_xmlparser.parseBuffer with dbms_xmlparser.parse(p,'c:/Desktop/family.xml'), its giving me an error invalid resource handle or path name 'c:/Desktop/famil.xml'. The xml file is - Sarah Bob Joanne Jim – Navin May 03 '11 at 06:29
  • @Navin: your XML document looks OK. See my edit for an example of using `dbms_xmlparser.parse`. – Luke Woodward May 03 '11 at 22:05
  • yeah, i have one more problem on this for the above xml and for the code above i have added one more procedure to print the name and value of all the nodes: and i am getting the value of a node as nothing(i mean null).. and the respective code is in the next comment – Navin May 04 '11 at 08:25
  • @Navin, and whoever approved your edit to my answer: please don't add your code to my answer in future. I didn't write your code, so it shouldn't be in my answer unless I put it there. Your editing did not follow the SO 'How to Edit' guidelines at all, and I'm not happy with you for doing this to my answer. In future, please either edit your question, or ask a separate follow-on question. – Luke Woodward May 04 '11 at 21:55