我需要提取XML标记值,如下面的代码所示。
set serveroutput on
declare
lv_xml varchar2(500);
xmlstring XMLTYPE;
lv_val varchar2(10);
BEGIN
lv_xml :=
'<?xml version="1.0" encoding="UTF-8"?>
<TestMain xmlns="http://www.w3.org/2001/XMLSchema-instance">
<testTag1>VAL 1</testTag1>
<testTag2>VAL 2</testTag2>
<testTag3>VAL 3</testTag3>
</TestMain>';
xmlstring := XMLTYPE.CREATEXML(lv_xml);
SELECT EXTRACTVALUE(VALUE(fd), 'testTag2')
INTO lv_val
FROM TABLE(XMLSEQUENCE(xmlstring.EXTRACT('TestMain'))) f,
TABLE(XMLSEQUENCE(EXTRACT(VALUE(f),
'TestMain/testTag2'))) fd;
dbms_output.put_line('Val: '||lv_val);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error: '||SQLCODE||' '||SQLERRM);
END;
/
当我运行它时,我收到异常ORA-01403: no data found
。
我发现,如果我删除XML命名空间xmlns="http://www.w3.org/2001/XMLSchema-instance"
,那么它工作正常。但是,我将从中提取值的XML流将采用此格式(即,它将包含命名空间)。
有没有办法能够在xmlns存在的情况下提取值?
答案 0 :(得分:2)
你在这里:
declare
lv_xml varchar2(500);
xmlstring XMLTYPE;
lv_val varchar2(10);
BEGIN
lv_xml :=
'<?xml version="1.0" encoding="UTF-8"?>
<TestMain xmlns="http://www.w3.org/2001/XMLSchema-instance">
<testTag1>VAL 1</testTag1>
<testTag2>VAL 2</testTag2>
<testTag3>VAL 3</testTag3>
</TestMain>';
xmlstring := XMLTYPE.CREATEXML(lv_xml);
SELECT EXTRACTVALUE(VALUE(fd), '.')
INTO lv_val
FROM TABLE(XMLSEQUENCE(xmlstring.EXTRACT('/TestMain', 'xmlns="http://www.w3.org/2001/XMLSchema-instance"'))) f,
TABLE(XMLSEQUENCE(EXTRACT(VALUE(f), '/TestMain/testTag2', 'xmlns="http://www.w3.org/2001/XMLSchema-instance"'))) fd
;
dbms_output.put_line('Val: '||lv_val);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error: '||SQLCODE||' '||SQLERRM);
END;
/
为了代码可读性,您可以将select
内部的特定内容写为
SELECT EXTRACTVALUE(xmlstring, '/TestMain/testTag2', 'xmlns="http://www.w3.org/2001/XMLSchema-instance"')
INTO lv_val
FROM dual;
或甚至更具可读性(虽然在功能上不是100%相同)
lv_val := xmlstring.extract('/TestMain/testTag2/text()', 'xmlns="http://www.w3.org/2001/XMLSchema-instance"').getStringVal();