Pregunta

Estoy tratando de leer un XML del procedimiento PLSQL usando el paquete XMLParser, recibo este 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 es mi nombre de procedimiento, y no hay declaraciones en la línea número 75, y la siguiente línea contiene p := xmlparser.newParser.

¿Alguien puede ayudarme a resolver este problema? O sugiera una forma simple de leer XML en PLSQL.

¿Fue útil?

Solución

Has proporcionado pocos detalles sobre lo que realmente estás haciendo, así que me temo que solo puedo adivinar.

No puedo reproducir el mensaje de error que tienes, pero solo he probado algunas cosas. ¿Quizás estás llamando a las API de Oracle XML incorrectamente? ¿Quizás hay algo extraño en el documento XML que está intentando analizar? Me temo que no tengo idea, ya que no nos has dado la fuente de tu DOMSAMPLE Procedimiento ni el documento XML que está intentando analizar.

No puedo creer que la línea 75 de su procedimiento sea una línea en blanco. ¿Es esta línea 75 del procedimiento, o la línea 75 del archivo que contiene el procedimiento?

Aquí hay un ejemplo usando DBMS_XMLPARSER y DBMS_XMLDOM. Simplemente lee el nombre del elemento raíz de la cadena XML dada:

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

Cuando ejecuto esto me da la salida Tag name is thisIsATest.

En cuanto a formas más simples de leer XML, Hay una en una pregunta que respondí antes. No sé si eso te ayudará, porque sé muy poco sobre lo que estás tratando de lograr.

Finalmente, no cree objetos en el SYS esquema.

EDITAR: En tu comentario, mencionas que estás usando dbms_xmlparser.parse en vez de dbms_xmlparser.parseBuffer. Tuve una jugada con dbms_xmlparser.parse y presione el mismo error de 'manejo de recursos o nombre de ruta' no válido varias veces antes de finalmente encontrar algo que funcionara. A continuación se muestra lo que logré trabajar; Bien puede haber una mejor solución a lo que desea que esto.

Antes de que pueda hacer una E/S de archivo con Oracle, y eso parece incluir el uso de dbms_xmlparser.parse, Primero debe crear un 'directorio' de Oracle. Los directorios en Oracle corresponden a directorios en el sistema de archivos. Tenga en cuenta que este es el sistema de archivos en la máquina en la que se ejecuta la base de datos Oracle. Si el archivo XML no está en el mismo sistema de archivos (por ejemplo, la base de datos Oracle está en un servidor y su archivo XML está en su PC de desarrollo), no podrá usar dbms_xmlparser.parse, a menos que primero transfiera este archivo a un directorio en el sistema de archivos del servidor de la base de datos.

Comenzaré creando un directorio Oracle correspondiente a un directorio en mi sistema de archivos:

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

Directory created.

Estoy usando Linux aquí. Si está utilizando Windows, no dude en revertir la dirección de las cortes.

Antes de ir más allá, echemos un vistazo rápido al archivo XML en el que leeremos:

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

En SQL*plus, host envía el resto de la línea al shell, o cmd.exe En Windows. En Windows también usarías type en vez de cat.

Finalmente, aquí hay un bloque PL/SQL que lee este archivo XML:

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>

La única diferencia entre este bloque y la más arriba es que la línea que llamó dbms_xmlparser.parseBuffer ha sido reemplazado por dos líneas. La primera de estas dos líneas llama dbms_xmlparser.setBaseDir para establecer un directorio base para el analizador y la segunda llamada dbms_xmlparser.parse usando un nombre de archivo relativo a este directorio.

Editar 2: Su código, que no funcionó como esperaba, y que editó en mi respuesta, es el siguiente:

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;

Aparentemente, esto estaba devolviendo todos los valores como nulos, como lo sugiere el último de los tres comentarios.

Citar una respuesta anterior mía en una pregunta similar:

En XML DOM, los elementos no tienen ningún 'valor' para hablar. Los nodos de elementos contienen nodos de texto como niños, y son estos nodos los que contienen los valores que desea.

Entonces, intente reemplazar la línea

      nodeval := xmldom.getNodeValue(n);

con

      nodeval := xmldom.getNodeValue(xmldom.getFirstChild(n));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top