Чтение ошибок XML из процедуры PLSQL
Вопрос
Я пытаюсь прочитать XML из процедуры PLSQL, используя пакет XmlParser, я получаю эту ошибку
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
это имя моей процедуры, и нет заявлений на строке № 75, и следующая строка содержит p := xmlparser.newParser
.
Кто -нибудь может помочь мне в решении этой проблемы. Или предложить простой способ прочитать XML в PLSQL.
Решение
Вы предоставили скудные подробности о том, что вы на самом деле делаете, поэтому я боюсь, что могу только догадываться.
Я не могу воспроизвести сообщение об ошибке, которое у вас есть, но я пробовал только несколько вещей. Возможно, вы неправильно звоните 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> create or replace directory ora_dir as '/home/luke/ora_dir'; Directory created.
Я использую Linux здесь. Если вы используете Windows, не стесняйтесь обратить вспять направление ударов.
Прежде чем мы пойдем дальше, давайте быстро рассмотрим файл XML, в котором мы прочитаем:
SQL> host cat /home/luke/ora_dir/example.xml <?xml version="1.0" ?> <root> <child /> </root>
В SQL*Plus, host
отправляет оставшуюся линию на оболочку, или cmd.exe
в окнах. В окнах вы также используете type
вместо cat
.
Наконец, вот блок PL/SQL, который считывает этот файл 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>
Единственная разница между этим блоком и дальнейшим вверх заключается в том, что линия, которая называется 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));