create local temp table tmp_element as
select
    xn.dewey,
    xt.name
from
    xml_node xn,
    xml_tag xt
where
    xn.docid = 28 and
    xn.tagid = xt.tagid and
    xn.kind = '1';
--explain analyze
create or replace view vw_tocat as
-- Element
select
    vw.dewey as dewey,
    1 as seq,
    '<' || vw.name as parsed_text
from
    tmp_element vw
union all
-- Attibute, namespace decl
select
    xn.dewey,
    xn.kind - 3,
    case
        when xn.kind = '5' then
            ' ' || xa.name || '="' || xn.value || '"'
        else
            '' || ns.name || '="' || xn.value || '"'
    end
from
    xml_node xn left join xml_attribute xa using(tagid)
    left join xml_namespace ns using(tagid)
where
    xn.docid = 28 and
    xn.kind = '5' or xn.kind = '6'
union all
-- right delimiter(element)
select
    vw.dewey + 1,
    4 as seq,
    '>'
from
    tmp_element vw
union all
-- text,comment
select
    xn.dewey,
    5,
    case
        when xn.kind = '3' then
            '<!-- ' || xn.value || ' -->'
        else
            xn.value
    end
from
    xml_node xn
where
    xn.docid = 28 and
    xn.kind = '2' or xn.kind = '3'
union all
-- pi
select
    xn.dewey,
    5,
    '<?' || pi.name || xn.value || '?>'
from
    xml_node xn,
    xml_pi pi
where
    xn.docid = 28 and
    xn.tagid = pi.tagid and
    xn.kind = '4'
union all
-- closing tag
select
    vw.dewey + 2147483647,
    6 as seq,
    '</' || vw.name || '>'
from
    tmp_element vw
order by dewey, seq;
explain analyze
select list(parsed_text) from vw_tocat;