0

I have a table named data with a column desc_data. The value of this column is as below :

<span class ="label">A</span><br> <span class ="value">A-Class</span> <span class ="label">B</span><br> <span class ="value">B-Class</span>.

I want to parse this column value,strip html tags and into a new view split it using sql query(Regexp_Replace maybe) such that: All label values become columns, i.e.

<span class ="label"> A & <span class ="label">B will become columns, and

<span class ="value">A-Class & <span class ="value">B-Class will become the column value respectively.

The actual data is much more with many labels and values however this is just sample to get help. The expected result should be:

View data_View

A          B
A-Class    B-Class

2 Answers 2

1

I think it would be much more convenient to get required data as rows, not columns. And you can parse it using xmltable with a little modification of your original html (removing unclosed tags like <br>. that's why <br/> is better):

with t as (
  -- your sample data:
  select
    q'[<span class ="label">A</span><br> <span class ="value">A-Class</span> <span class ="label">B</span><br> <span class ="value">B-Class</span>.
  ]' html_data
from dual
)
-- main query:
select xt.*
from t
    ,xmltable(
      'let $labels := /root/span[@class eq "label"]
       let $values := /root/span[@class eq "value"]
       for $label at $i in $labels
          return element label {
             attribute name {$label/text()}, 
             attribute value {$values[$i]/text()}
          }
       '
      passing
      xmltype(
       --- modify your html to make it compatible with xml:
       '<root>'
       || replace(replace(t.html_data,'<br>'),'&nbsp;')
       ||'</root>'
      )
      columns
         n for ordinality,
         label_name path '@name',
         label_value path '@value'
    ) xt;

Result:

         N LABEL_NAME                     LABEL_VALUE
---------- ------------------------------ ------------------------------
         1 A                              A-Class
         2 B                              B-Class
Sign up to request clarification or add additional context in comments.

3 Comments

Hi Sayan, when i checked for bigger and real data. At palces it is throwing error. ex: when tag is something like <span class="desc_label">Domain</span><br><span class="select desc_value" data-option_list="RAD_PIGMENT_ID" cust="Rad_Pigment_Id" style="display: block;">Production</span> <span class="desc_label">Project Team </span><br><span class="desc_value">Asdsh jsdja&nbsp;kajdhjahdja Grueber, Here for label domain instead of the value Production, it takes the next tag's value,i.e. Asdsh jsdja&nbsp;kajdhjahdja Grueber which should have come against Project team
basically a way to modify let $values := /root/span[@class eq "desc_value"], so that it also includes let $values := /root/span[@class eq " select desc_value"]
1

You need to split your string by some pattern( such as '/span> <span' ) recursively. Extract the desired column by using REGEXP_REPLACE() function, and then apply pivoting :

WITH t(desc_data) AS
(
 SELECT '<span class ="label">A</span><br> <span class ="value">A-Class</span> <span class ="label">B</span><br> <span class ="value">B-Class</span> <span class ="label">C</span><br> <span class ="value">C-Class</span>'
   FROM dual
), t2 AS
(
SELECT SUBSTR(desc_data,1,CASE WHEN INSTR(desc_data,'/span> <span',1,level) > 0
                               THEN INSTR(desc_data,'/span> <span',1,level) + 5 
                               ELSE LENGTH(desc_data)
                           END
             ) AS desc_data2
  FROM t
 CONNECT BY level <= REGEXP_COUNT(desc_data,'/span> <span') + 1
)
SELECT *
  FROM
  (
   SELECT REGEXP_REPLACE(desc_data2,'(.*"label">)(\S+)(</span>.*)','\2') AS label,
          REGEXP_REPLACE(desc_data2,'(.*"value">)(\S+)(</span>.*)','\2') AS value
     FROM t2 )
 PIVOT ( MAX(VALUE) FOR LABEL IN ('A' AS "A", 'B' AS "B", 'C' AS "C") );


A          B          C
-------    -------    -------
A-Class    B-Class    C-Class 

Demo

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.