使用命名空间提取XML标记

时间:2014-07-17 14:26:06

标签: sql xml plsql xml-namespaces

我需要提取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存在的情况下提取值?

1 个答案:

答案 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();