通过混合 DBMS_XMLDOM 功能和 REGEXP_SUBSTR,您最终会得到一个解决方案,这要归功于 writeToBuffer() 重写 XML,以便根节点仅位于 1 行:
CREATE OR REPLACE TYPE STRING_T AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION xmlrootnamespaces(p_xml IN VARCHAR2)
RETURN T_STRING
PIPELINED
IS
v_buf CLOB ;
v_roottag VARCHAR2(4000);
PRAGMA UDF;
BEGIN
v_roottag := DBMS_XMLDOM.getTagName(DBMS_XMLDOM.getDocumentElement(DBMS_XMLDOM.newDOMDocument(xmltype(p_xml)))) ;
DBMS_XMLDOM.writeToBuffer(DBMS_XMLDOM.makeNode(DBMS_XMLDOM.newDOMDocument(p_xml)), v_buf);
v_roottag := regexp_substr(v_buf, '<' || v_roottag || '.*>');
FOR rec in (
select regexp_substr(p_xml,
'xmlns.*?=[^[:space:]]*', 1, level) as ns
from dual
connect by level <= regexp_count(p_xml, 'xmlns.*?=[^[:space:]]*')
)
LOOP
PIPE ROW(rec.ns);
END LOOP ;
RETURN ;
END ;
/
select * from xmlrootnamespaces(q'~<?xml version="1.0" encoding="UTF-8"?>
<my_xml
xmlns="http://example.com/ns1"
xmlns:foo="http://example.com/ns2">
<aaa></aaa>
<myelement>
<foo:bbb />
</myelement>
</my_xml>~') ;
COLUMN_VALUE
------------------------------------------------
xmlns="http://example.com/ns1"
xmlns:foo="http://example.com/ns2">
适应您的进一步需求。