2016-03-23 14 views
0

Aşağıda, Oracle 11g veritabanından (bu basit örnekte ikili tabloyu kullanıyorum) bir düz dosyaya veri almak için basit bir örnek verilmiştir.XML çıktı dosyasındaki yanlış biçim ve neden emin değilim

Dosyadaki aşağıdaki formatı bekliyorum.

<message> 
    <production> 
    <prodCategoryType>test type 1</prodCategoryType> 
    <prodStatusType>prod status 1</prodStatusType> 
    </production> 
</message> 
<message> 
<production> 
    <prodCategoryType>test type 2</prodCategoryType> 
    <prodStatusType>prod status 2</prodStatusType> 
</production> 
</message> 

ama başlangıç ​​mesajı ve üretim etiketi eksik ve ortada> garip bir koyarak gibi görünüyor, hangi aşağıda yerine alıyorum.

<message> 
    <production> 
    <prodCategoryType>test type 1</prodCategoryType> 
    <prodStatusType>prod status 1</prodStatusType> 
    </production> 
</message> 
on> 
    <prodCategoryType>test type 2</prodCategoryType> 
    <prodStatusType>prod status 2</prodStatusType> 
    </production> 
</message> 

Yanlış bir şey yapıyorum ???

DECLARE 

l_file UTL_FILE.FILE_TYPE; 
l_clob CLOB; 
l_buffer VARCHAR2(32767); 
l_amount BINARY_INTEGER := 32767; 
l_pos  INTEGER := 1; 
l_extract_dir    CONSTANT dba_directories.directory_name%TYPE:= 'REPORTS_OUT_DIR'; -- \\data2\data\download\d7prdv1\prsrepreports 


l_xmltype XMLTYPE; 
l_domdoc dbms_xmldom.DOMDocument; 
l_root_node dbms_xmldom.DOMNode;  

l_message_node   dbms_xmldom.DOMNode; 

l_production_element dbms_xmldom.DOMElement; 
l_production_node  dbms_xmldom.DOMNode; 

-- production XML elements, node, text 
l_prod_element     dbms_xmldom.DOMElement;  
l_prod_node   dbms_xmldom.DOMNode; 
l_prod_t_node   dbms_xmldom.DOMNode; 
l_prod_text   dbms_xmldom.DOMText; 
-- production XML elements, node, text, node 

CURSOR c_production 
IS SELECT 'test type 1',   as prodCategoryType 
      'prod status 1'   as prodStatusType 
    from dual    
    UNION 
    SELECT 'test type 2',   as prodCategoryType 
      'prod status 2'   as prodStatusType 
    from dual; 

BEGIN 
UTL_FILE.FCLOSE_ALL; -- make sure all file handles are closed for session 
l_file := UTL_FILE.fopen(l_extract_dir , 'Sample2.dat', 'w', 32767); 

-- Create an empty XML document 
    l_domdoc := dbms_xmldom.newDomDocument; 

-- Create a root node 
l_root_node := dbms_xmldom.makeNode(l_domdoc); 

-- Create a message root node 
l_message_node := dbms_xmldom.appendChild(l_root_node, dbms_xmldom.makeNode(dbms_xmldom.createElement(l_domdoc, 'message')) 
            );  

FOR production_rec in c_production LOOP 

    l_production_element := dbms_xmldom.createElement(l_domdoc, 'production'); 
    l_production_node := dbms_xmldom.appendChild(l_message_node,dbms_xmldom.makeNode(l_production_element)); 

    -- prodCategoryType 
    l_prod_element := dbms_xmldom.createElement(l_domdoc, 'prodCategoryType'); 
    l_prod_node := dbms_xmldom.appendChild(l_production_node,dbms_xmldom.makeNode(l_prod_element)); 
    l_prod_text := dbms_xmldom.createTextNode(l_domdoc, production_rec.prodCategoryType); 
    l_prod_t_node := dbms_xmldom.appendChild(l_prod_node,dbms_xmldom.makeNode(l_prod_text)); 

    -- prodStatusType 
    l_prod_element := dbms_xmldom.createElement(l_domdoc, 'prodStatusType'); 
    l_prod_node := dbms_xmldom.appendChild(l_production_node,dbms_xmldom.makeNode(l_prod_element)); 
    l_prod_text := dbms_xmldom.createTextNode(l_domdoc, production_rec.prodStatusType); 
    l_prod_t_node := dbms_xmldom.appendChild(l_prod_node,dbms_xmldom.makeNode(l_prod_text)); 


     l_xmltype := dbms_xmldom.getXmlType(l_domdoc); 
     l_clob  := l_xmltype.getClobVal; 
     DBMS_LOB.read (l_clob, l_amount, l_pos, l_buffer); 
     UTL_FILE.put(l_file, l_buffer); 
     l_pos := l_pos + l_amount; 

    END LOOP; 

dbms_xmldom.freeDocument(l_domdoc); 
UTL_FILE.fclose(l_file); 

END; 

cevap

0

İki şeyi yanlış yapıyorsunuz gerçekten. Şey, üç. Beklemediğiniz çıktı, kök düğüm olmadığı için geçerli bir XML değildir; daha önceki sorulardan (AV-XML?) bunu atlamış olabilirsiniz, fakat açık değildir.

Gerçekten üretmekte olduğunuz şey geçerli olsa da, beklediğiniz biçimde değil. döngünün l_xmltype ilk yinelemenin içeren sonra:

<message> 
    <production> 
    <prodCategoryType>test type 1</prodCategoryType> 
    <prodStatusType>prod status 1</prodStatusType> 
    </production> 
</message> 

... hangi beklediğiniz şeydir. Ama ikinci döngü sonra, ikinci üretim düğüm aynı mesajı düğümünün altında yerleştirilir, böylece var:

<message> 
    <production> 
    <prodCategoryType>test type 1</prodCategoryType> 
    <prodStatusType>prod status 1</prodStatusType> 
    </production> 
    <production> 
    <prodCategoryType>test type 2</prodCategoryType> 
    <prodStatusType>prod status 2</prodStatusType> 
    </production> 
</message> 

Eğer kapanış </message> sonunda oturan l_pos terk dosyaya dışarı ilk yazma yaptığınızda etiketi ve görmeyi beklediğiniz yapıya sahip olduğunuzu varsayıyorsunuz, bir sonraki döngüde, bir sonraki char, ikinci <message> etiketinin başlangıcı olacaktır. Ancak (tek) kapanış etiketi artık taşındığından, l_pos aslında yeni eklenen ikinci <production> etiketinin ortasındadır. Oku bu noktadan alır, yani bu açılış etiketinin on> bölümünden.

Yapmanız gereken en önemli şey, XML nesnesini çıktıdan dosyaya ayırmaktır. Daha sonra elde edip gerçek XML yansıtan bir dosya olacak

... 
    l_prod_t_node := dbms_xmldom.appendChild(l_prod_node,dbms_xmldom.makeNode(l_prod_text)); 

    /* Remove all existing conversion/writing from the first loop 
     l_xmltype := dbms_xmldom.getXmlType(l_domdoc); 
     l_clob  := l_xmltype.getClobVal; 
     DBMS_LOB.read (l_clob, l_amount, l_pos, l_buffer); 
     UTL_FILE.put(l_file, l_buffer); 
     l_pos := l_pos + l_amount; 
    */ 
    END LOOP; 

    WHILE l_pos <= dbms_lob.getlength(l_clob) LOOP 
    DBMS_LOB.read (l_clob, l_amount, l_pos, l_buffer); 
    UTL_FILE.put(l_file, l_buffer); 
    UTL_FILE.fflush(l_file); 
    l_pos := l_pos + l_amount; 
    END LOOP; 
    UTL_FILE.fclose(l_file); 
END; 
/

: yaptığınızı olarak DOM oluşturmak için bir döngü var, o zaman ayrı bir döngü sonradan dosyaya XML yazmak için . Daha sonra nesneyi farklı bir kök düğümüne sahip olacak şekilde ayarlayabilir ve döngü içindeki mesaj ve üretim düğümlerini ekleyebilirsiniz. Yapıyı yalnızca ilk döngüde l_message_node := ... satırını hareket ettirerek alabilirsiniz.

+0

Bu harika Alex Poole. –

+0

sadece koştu, şimdi alabileceğim tek sorun şu ki, en fazla clob almayı ve daha fazla baskı yapmama ve kısmi bir sekmeyi aşağıda görüyorum. Test1 TEST_1_TEST Test1

+0

Ben de eklenecek/yazma gerekiyor galiba Üretim düğümü düğümünün her yinelemesini dosyalayın. –

İlgili konular