Oracle包XMLDOM建立XML檔案及其缺點

來源:互聯網
上載者:User
Oracle有一個包XMLDOM,可以很方便的建立XML檔案.舉個簡單的例子.產生Test.xml,內容如下

   <staff content = "name and id">

         <member >

              <name>Arwen</name>

              <eno>123</eno>

        </member>

         <member >

              <name>Tom</name>

              <eno>456</eno>

        </member>   

  </staff>

---------------------------------------------------------------------------------------------------------------------------------------

--產生xml的代碼

declare
    doc  XMLDOM.DOMDOCUMENT;
    doc_node  XMLDOM.DOMNODE;
    root_node  XMLDOM.DOMNODE;
    user_node XMLDOM.DOMNODE;
    item_node XMLDOM.DOMNODE;
 
    root_elmt XMLDOM.DOMELEMENT;
    user_elmt XMLDOM.DOMELEMENT;
    item_elmt XMLDOM.DOMELEMENT;

    item_text XMLDOM.DOMTEXT;

 begin
   doc := XMLDOM.NEWDOMDOCUMENT;
   xmldom.setVersion(doc, '1.0');
   xmldom.setCharset(doc, 'UTF-8');
   --根節點
   doc_node := XMLDOM.MAKENODE(doc);
   root_elmt := XMLDOM.CREATEELEMENT(doc,'staff');
   XMLDOM.SETATTRIBUTE(root_elmt,'content ','name and id');
   root_node:=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(root_elmt));
  
   --節點1
   user_elmt := XMLDOM.CREATEELEMENT(doc,'member');
   user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));
  
     item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');
     item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
     item_text := XMLDOM.CREATETEXTNODE(doc,'Arwen');
     item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
    
     item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');
     item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
     item_text := XMLDOM.CREATETEXTNODE(doc,'123');
     item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
    
     --節點2
     user_elmt := XMLDOM.CREATEELEMENT(doc,'member');
     user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));
  
     item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');
     item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
     item_text := XMLDOM.CREATETEXTNODE(doc,'tom');
     item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
    
     item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');
     item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
     item_text := XMLDOM.CREATETEXTNODE(doc,'456');
     item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
    
     --寫入作業系統檔案中
     XMLDOM.WRITETOFILE(doc,'DIR'||'\Test.xml');--注意必須先建立一個檔案目錄dir
     --可以通過語句 : create or replace directory dir as 'd:\temp'

    

    XMLDOM.FREEDOCUMENT(doc);

 end;

 

這樣產生XML檔案非常方便,能滿足一般的應用了.但是XMLDOM有個缺點,就是一次性在記憶體中產生所有xml檔案內容,然後寫入到磁碟檔案中.如果xml檔案太大,比如說有個table有幾個G,想把它儲存成xml檔案.這樣可能就會出現記憶體不足,組建檔案失敗.那該咋整呢?

 

1.可能首先想到的是用UTL_FILE去組建檔案.

裡面的內容全部手動寫成xml格式的,然後儲存成xml尾碼的檔案.這樣確實可行.但有個麻煩問題時如果一些節點內容含有xml的五個保留字元的話(&,<,>,'," 分別是和號,小於符號,大於符號,單引號,雙引號),我們如果以文本方式開啟xml檔案是看不到節點內容裡面有這些保留字的,都轉換成了對應的&amp, &gt, &lt, &apos, &quot.節點指定的是上面的Arwen或123,假如有名字(A&r<w>e'n")則儲存到xml檔案中應該改成(A&ampr&gtw&lte&aposn&quot).如果用xmldom會預設去轉換,不用我們管了.如果用UTL_FILE必須手動寫代碼去轉換.

 

2.結合使用XMLDOM和utl_file

假如有表staff(name varchar2(30), eno integer),裡面有幾個G的內容,要轉換成開頭講的那種格式的xml檔案

--產生xml的代碼其中XML檔案的頭和尾用UTL_FILE直接寫入檔案中,節點內容用xmldom產生,然後寫到clob變數中,再把clob變數值用utl_file寫入到xml檔案中

 

declare

 

  STAFFINFO  UTL_FILE.FILE_TYPE;

  v_temp clob;

  cursor c_table_info is

          select name,eno from staff;

  v_name varchar2(30);

 v_eno integer;

    doc  XMLDOM.DOMDOCUMENT;
   doc_node XMLDOM.DOMNODE;
   root_node XMLDOM.DOMNODE;
    user_node XMLDOM.DOMNODE;
    item_node XMLDOM.DOMNODE;
 
    root_elmt XMLDOM.DOMELEMENT;
    user_elmt XMLDOM.DOMELEMENT;
    item_elmt XMLDOM.DOMELEMENT;

    item_text XMLDOM.DOMTEXT;

begin

   --xml header
    STAFFINFO :=utl_file.fopen_nchar('DIR','Test.xml','W',32767);--跟前面說的一樣必須先建立一個directory才行

     UTL_FILE.PUT_LINE_NCHAR(STAFFINFO
,'<staff content = "name and id">');

     UTL_FILE.FFLUSH(STAFFINFO );--直接寫入到磁碟檔案中,不會停留在記憶體中
     UTL_FILE.FCLOSE(STAFFINFO );

  

open c_table_info;

loop

   fetch c_table_info into v_name,v_eno;

exit when c_table_info%notfound;

 
   --XML節點

  doc := XMLDOM.NEWDOMDOCUMENT;
   xmldom.setCharset(doc, 'UTF-8');

    doc_node := XMLDOM.MAKENODE(doc);

   user_elmt := XMLDOM.CREATEELEMENT(doc,'member');
   user_node :=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(user_elmt));
  
     item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');
     item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
     item_text := XMLDOM.CREATETEXTNODE(doc,v_name);
     item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));
    
     item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');
     item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));
     item_text := XMLDOM.CREATETEXTNODE(doc,'eno');
     item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text)); 
     

      v_temp :=' ';
        --寫入到臨時變數v_temp中
     XMLDOM.WRITETOCLOB(doc,v_temp);

     STAFFINFO :=utl_file.fopen_nchar('DIR','Test.xml','A',32767);--以a模式會在檔案後新增內容,用w會覆蓋之前的內容

    UTL_FILE.PUT_LINE_NCHAR(STAFFINFO
,v_temp);

     UTL_FILE.FFLUSH(STAFFINFO );

     UTL_FILE.FCLOSE(STAFFINFO ); 

    XMLDOM.FREEDOCUMENT(doc);

end loop;

close c_table_info;

 

--xml tail

   STAFFINFO :=utl_file.fopen_nchar('DIR','Test.xml','a',32767);

    UTL_FILE.PUT_LINE_NCHAR(STAFFINFO
,'</staff>');

     UTL_FILE.FFLUSH(STAFFINFO );

     UTL_FILE.FCLOSE(STAFFINFO );

 

end;

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.