select id, string
,substr(string, instr(string, '<', 1, element_number)
,instr(string, '>', 1, element_number) - instr(string, '<', 1, element_number) + 1) result
from test
cross join
(
select level element_number from dual connect by level <=
(select max(length(string) - length(replace(string, '<', null))) max_elements from test)
) extra_rows
where element_number <= length(string) - length(replace(string, '<', null))
order by id, element_number;