Ошибка чтения xml из процедуры plsql

Я пытаюсь прочитать XML из процедуры plsql с помощью пакета xmlparser, я получаю эту ошибку

ORA-31020: операция не разрешена, причина: не поддерживается
ORA-06512: в "XDB.DBMS_XMLPARSER", строка 395
ORA-06512: в "SYS.DOMSAMPLE", строка 75
ORA-06512: в строке 2

DOMSAMPLE мое имя процедуры, и нет никаких операторов в строке номер 75, а следующая строка содержит p := xmlparser.newParser,

Может кто-нибудь, пожалуйста, помогите мне в решении этой проблемы. Или предложите простой способ чтения XML в plsql.

1 ответ

Решение

Вы предоставили мало подробностей о том, что вы на самом деле делаете, так что, боюсь, я могу только догадываться.

Я не могу воспроизвести сообщение об ошибке, которое вы получили, но я пробовал только несколько вещей. Возможно, вы неправильно называете API Oracle XML? Возможно, есть что-то странное в 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 схемы.

РЕДАКТИРОВАТЬ: в своем комментарии вы упоминаете, что вы используете dbms_xmlparser.parse вместо dbms_xmlparser.parseBuffer, Я поиграл с dbms_xmlparser.parse и несколько раз нажмите одну и ту же ошибку "недопустимый дескриптор ресурса или имя пути", прежде чем, наконец, найдете что-то работающее Ниже то, что мне удалось получить работу; вполне может быть лучшее решение того, что вы хотите, чем это.

Прежде чем вы сможете выполнить какой-либо файловый ввод / вывод с Oracle, и это включает в себя использование dbms_xmlparser.parseВы должны сначала создать "каталог" Oracle. Каталоги в Oracle соответствуют каталогам в файловой системе. Обратите внимание, что это файловая система на компьютере, на котором работает база данных Oracle. Если XML-файл не находится в той же файловой системе (например, база данных Oracle находится на сервере, а ваш XML-файл находится на компьютере разработчика), вы не сможете использовать dbms_xmlparser.parse, если вы сначала не перенесете этот файл в каталог в файловой системе сервера базы данных.

Я начну с создания каталога Oracle, соответствующего каталогу в моей файловой системе:

SQL> создать или заменить каталог ora_dir как '/home/luke/ora_dir';

Каталог создан.

Я использую Linux здесь. Если вы используете Windows, не стесняйтесь менять направление слешей.

Прежде чем идти дальше, давайте кратко рассмотрим XML-файл, в котором мы будем читать:

SQL> host cat /home/luke/ora_dir/example.xml<Корень>
  <ребенок />

В SQL*Plus host отправляет остаток строки в оболочку, или cmd.exe на винде. В Windows вы также используете type вместо cat,

Наконец, вот блок PL/SQL, который читает этот файл XML:

SQL> установить выход сервера
SQL> ОБЪЯВИТЬ
  2     p    dbms_xmlparser.parser;
  3 д dbms_xmldom.domdocument;
  4     e    dbms_xmldom.domelement;
  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;

Это, по-видимому, возвращало все значения как нулевые, как предлагалось в последнем из трех комментариев.

Процитирую мой предыдущий ответ на похожий вопрос:

В XML DOM элементы не имеют никакого "значения", о котором можно говорить. Узлы элементов содержат текстовые узлы как дочерние элементы, и именно эти узлы содержат нужные значения.

Итак, попробуйте заменить строку

      nodeval := xmldom.getNodeValue(n);

с

      nodeval := xmldom.getNodeValue(xmldom.getFirstChild(n));
Другие вопросы по тегам