PLSQLプロシージャからXMLを読み取るエラー
質問
XMLParserパッケージを使用してPLSQL手順からXMLを読み取ろうとしています。このエラーが発生しています
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
.
誰かがこの問題を解決するのを手伝ってくれませんか。または、PLSQLでXMLを読む簡単な方法を提案します。
解決
あなたは実際に何をしているのかについての詳細がわずかに少ないので、推測できるのではないかと思います。
あなたが持っているエラーメッセージを再現することはできませんが、私はいくつかのことしか試しませんでした。おそらくあなたはOracle XML APIを間違って呼んでいますか?おそらく、あなたが解析しようとしている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を読む簡単な方法については、 私が以前に答えた質問には1つあります. 。あなたが達成しようとしていることについてほとんど知らないので、それがあなたを助けるかどうかはわかりません。
最後に、でオブジェクトを作成しないでください SYS
スキーマ。
編集: :あなたのコメントで、あなたはあなたが使用していることに言及します dbms_xmlparser.parse
それ以外の dbms_xmlparser.parseBuffer
. 。私は遊びをしました dbms_xmlparser.parse
そして、同じ「無効なリソースハンドルまたはパス名」エラーを数回ヒットしてから、最終的に機能するものを見つけます。以下は私が何とか働いたものです。これよりもあなたが望むものに対するより良い解決策があるかもしれません。
Oracleを使用してI/Oを使用する前に、使用を含むように見えます dbms_xmlparser.parse
, 、最初にOracleの「ディレクトリ」を作成する必要があります。 Oracleのディレクトリは、ファイルシステムのディレクトリに対応しています。これは、Oracleデータベースが実行されるマシン上のファイルシステムであることに注意してください。 XMLファイルが同じファイルシステム上にない場合(たとえば、Oracleデータベースがサーバー上にあり、XMLファイルが開発PCにある場合、使用できません。 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
.
最後に、このXMLファイルを読み取るPL/SQLブロックを次に示します。
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
2行に置き換えられました。これらの2つの行のうち最初の呼び出し dbms_xmlparser.setBaseDir
パーサーのベースディレクトリを設定し、2回目の呼び出し 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;
これは、3つのコメントの最後で示唆されているように、すべての値をnullとして返すようです。
引用する 同様の質問に関する私の以前の答え:
XML DOMでは、要素には「価値」がありません。要素ノードには、子供としてテキストノードが含まれており、必要な値を含むのはこれらのノードです。
したがって、行を交換してみてください
nodeval := xmldom.getNodeValue(n);
と
nodeval := xmldom.getNodeValue(xmldom.getFirstChild(n));