Ошибка чтения 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 xml version = "1.0"?><Корень> <ребенок /> Корень>
В 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));