Вы предоставили мало информации о том, что вы на самом деле делаете, так что, боюсь, я могу только догадываться.
Я не могу воспроизвести сообщение об ошибке, которое у вас есть, но я пробовал только несколько вещей. Возможно, вы неправильно называете 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
.
EDIT : в своем комментарии вы упоминаете, что используете 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
в Windows. В Windows вы бы также использовали 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));