I want extract list of namespaces from my root element in Oracle PLSQL My xml is for example: (In real it can be very big)
<my_xml xmlns="http://example.com/ns1" xmlns:foo="http://example.com/ns2">
<aaa></aaa>
<myelement>
<foo:/bbb>
</myelement>
</my_xml>
I need it because I didn't know namespaces befere I receive the xml. It's automaticaly serialised and random. I need know namespaces to extract element "my_element" from xml. Thx for help.
I expected result as varchar2 variable with all namespaces:
"xmlns="http://example.com/ns1" xmlns:foo="http://example.com/ns2""
I tried what I know, but dbms_xmldom.getNamespace get me only first namespace of DMBSXMLemement. I can't acces to namespaces as to atributes. I want some nice standard solution. I know I can do it by some substr, instr() etc. I did't know if regular expressions are the good idea?
By mixing DBMS_XMLDOM functionality and REGEXP_SUBSTR, you eventually have a solution:
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_replace(
regexp_substr(p_xml,
'xmlns.*?=[[:space:]]*[^[:space:]]*', 1, level, 'im'),
'[[:space:]]', ''
)
as ns
from dual
connect by level <= regexp_count(p_xml, 'xmlns.*?=[[:space:]]*[^[:space:]]*', 1, 'im')
)
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">
Adapt to your further needs.