Skip to main content
 

Estrarre dati da un XML Type

E' spesso utile accedere ai dati contenuti in una vriabile XML TYpe, usando l' SQL come se fossero in una tabella o vista.

XML ha per sua stessa natura una struttura gerarchica. Di conseguenza viene facile pensare ad un file XML come a record di tabelle legate tra loro da relazioni master-detail.

Pensiamo ad un documento XML memorizzato nella colonna XML Type di una tabella Oracle:

<root> 
   <master id ='A'> 
    <info>First Header</info> 
      <detail> 
        <info>Detail 1</info> 
      </detail> 
      <detail> 
        <info>Detail 2</info> 
      </detail> 
   </master> 
   <master id = 'B'> 
      <info>Second Header</info> 
      <detail> 
           <info>Detail 3</info> 
      </detail> 
   </master>
</root>

Creeremo due viste ("dumb_master" e "dumb_detail") connesse da relazione master-detail relationship e popolate dai dati contenuti nell' XML Document della colonna dumb.dumber.

View "dumb_master"

CREATE OR REPLACE VIEW dumb_master AS
SELECT extractvalue(mstr, '/master/@id') master_id,       
       extractvalue(mstr, '/master/info') master_info,
       mstr master_xml
  FROM (SELECT VALUE(mstr) mstr
          FROM dumb,
               TABLE(xmlsequence(extract(dumber,
                                         '//master'))) mstr);

XMLSequence restituisce una sequenza di XMLType. Usando questa funzione in una "TABLE clause" possiamo mettere in serie i valori in righe multiple e processarle poi in una SELECT. Questa vista restituirà 2 record, una per ogni tag master in XML Document. View "dumb_master" restituirà tante righe quanti sono i tag 'master' all'interno del documento XML, 2 nel nostro caso. La colonna "master_xml" è di tipo "XML Type", contiene il tag master per il record corrente, e verrà usata dalla vista "dumb_detail". Per il record con "master_id" = A, "master_xml" conterrà:

<master id="A">
       <info>First Header</info>
       <detail>
            <info>Detail 1</info>
       </detail>
       <detail>
            <info>Detail 2</info>
       </detail>
</master>

View "dumb_detail"

CREATE OR REPLACE VIEW dumb_datail AS
SELECT master_id,
       extractvalue(dtl, '/detail/info') detail_info
  FROM (SELECT VALUE(dtl) dtl,
               master_id
          FROM dumb_master,
               TABLE(xmlsequence(extract(master_xml,
                                         '//detail'))) dtl);

"dumb_detail" è molto simile a "dumb_master". Una "select * restituirà:

A Detail 1
A Detail 2
B Detail 3

Questo è tutto. Queste tecniche possono essere usate per XML piccoli. Suggerisco le materialize views, per ridurre i tempi legati al esplosione dei file XML.

Oracle