2014-05-10 54 views
1

解析XML字符串,我收到了,我需要一個Oracle過程中接受並解析使用Oracle過程

我有一個可以解析XML文件的Oracle過程,而不是一個字符串 我的XML字符串我不知道如何修改現有的proc來解析字符串。請建議腳本是否準確,以及如何修改

我有一個XML作爲

<TWObject className="TWObject"> 
    <array size="240"> 
    <item> 
     <variable type="QuestionDetail"> 
     <questionId type="String"><![CDATA[30]]></questionId> 
     <questionType type="questionType"><![CDATA[COUNTRY]]></questionType> 
     <country type="String"><![CDATA[GB]]></country> 
     <questionText type="String"><![CDATA[Please indicate if the following "Type of Market Research" applies to your Project : <br><br>Detail Follow-up Study OR Message Recall Study fielded from a Lilly Call/Target List]]></questionText> 
     <optionType type="String"><![CDATA[RadioButton]]></optionType> 
     <answerOptions type="String[]"> 
      <item><![CDATA[Yes]]></item> 
      <item><![CDATA[No]]></item> 
     </answerOptions> 
     <ruleId type="String"><![CDATA[CRP_GB001]]></ruleId> 
     <parentQuestionId type="String"></parentQuestionId> 
     <parentQuestionResp type="String"></parentQuestionResp> 
     </variable> 
    </item> 
</array> 
</TWOject> 

我有一個可以解析XML文件作爲

Create or replace procedure parse_xml_data is 
l_bfile BFILE; 
l_clob CLOB; 
l_parser dbms_xmlparser.Parser; 
l_doc  dbms_xmldom.DOMDocument; 
l_nl  dbms_xmldom.DOMNodeList; 
l_n  dbms_xmldom.DOMNode; 
l_file  dbms_xmldom.DOMNodeList; 
l_filen  dbms_xmldom.DOMNode; 
lv_value VARCHAR2(1000); 
l_ch  dbms_xmldom.DOMNode; 

l_partname varchar2(100); 
l_filename varchar2(1000); 
l_temp VARCHAR2(1000); 
TYPE tab_type IS TABLE OF tab_data_parts%ROWTYPE; 
t_tab tab_type := tab_type(); 
BEGIN 
l_bfile := BFileName('DIR1', 'Parts.xml'); 
dbms_lob.createtemporary(l_clob, cache=>FALSE); 
dbms_lob.open(l_bfile, dbms_lob.lob_readonly); 
dbms_lob.loadFromFile(dest_lob => l_clob, src_lob => l_bfile, amount => dbms_lob.getLength(l_bfile)); 
dbms_lob.close(l_bfile); 
dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MON-YYYY'''); 

l_parser := dbms_xmlparser.newParser; 

dbms_xmlparser.parseClob(l_parser, l_clob); 
l_doc := dbms_xmlparser.getDocument(l_parser); 
dbms_lob.freetemporary(l_clob); 
dbms_xmlparser.freeParser(l_parser); 

l_nl := dbms_xslprocessor.selectNodes(dbms_xmldom.makeNode(l_doc),'/TWObject/array/item'); 

FOR cur_emp IN 0 .. dbms_xmldom.getLength(l_nl) - 1 LOOP 
l_n := dbms_xmldom.item(l_nl, cur_emp); 
t_tab.extend; 
dbms_xslprocessor.valueOf(l_n,'variable/text()',t_tab(t_tab.last).variable); 
dbms_xslprocessor.valueOf(l_n,'questionId/text()',t_tab(t_tab.last).questionId); 
dbms_xslprocessor.valueOf(l_n,'questionType/text()',t_tab(t_tab.last).questionType); 
dbms_xslprocessor.valueOf(l_n,'country/text()',t_tab(t_tab.last).country); 
dbms_xslprocessor.valueOf(l_n,'questionText/text()',t_tab(t_tab.last).questionText); 
dbms_xslprocessor.valueOf(l_n,'optionType/text()',t_tab(t_tab.last).optionType); 
//selecting the answerOptions 
l_file := dbms_xslprocessor.selectNodes(l_n,'answerOptions/item'); 
FOR cur_ch IN 0 .. dbms_xmldom.getLength(l_file) - 1 LOOP 
l_ch := dbms_xmldom.item(l_file, cur_ch); 
lv_value := dbms_xmldom.getnodevalue(dbms_xmldom.getfirstchild(l_ch)); 
if t_tab(t_tab.last).item is null then t_tab(t_tab.last).item := l_partname; end if; 
t_tab(t_tab.last).item := lv_value; 
t_tab.extend; 
END LOOP; 
END LOOP; 
t_tab.delete(t_tab.last); 
FOR cur_emp IN t_tab.first .. t_tab.last LOOP 
if t_tab(cur_emp).variable is not null and t_tab(cur_emp).item is not null then 
INSERT INTO tab_data_parts 
VALUES 
(t_tab(cur_emp).variable,t_tab(cur_emp).questionId,t_tab(cur_emp).questionType,t_tab(cur_emp).country,t_tab(cur_emp).questionText,t_tab(cur_emp).optionType, t_tab(cur_emp).item); 
end if; 

END LOOP; 
COMMIT;  
dbms_xmldom.freeDocument(l_doc); 
EXCEPTION 
WHEN OTHERS THEN 
dbms_lob.freetemporary(l_clob); 
dbms_xmlparser.freeParser(l_parser); 
dbms_xmldom.freeDocument(l_doc); 
END; 

回答

0

如果Oracle過程字符串小於32k,您可以直接將它分配給您的l_clob變量,其餘的將相同:

... 
BEGIN 
l_clob := '<TWObject className="TWObject"> 
    <array size="240"> 
    ... 
</array> 
</TWOject>'; 

dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MON-YYYY'''); 
l_parser := dbms_xmlparser.newParser; 
dbms_xmlparser.parseClob(l_parser, l_clob); 
... 

或者更靈活,添加一個CLOB參數到你的過程和你的字符串分配給調用者CLOB:

Create or replace procedure parse_xml_data (p_clob in clob) is 
l_parser dbms_xmlparser.Parser; 
l_doc  dbms_xmldom.DOMDocument; 
... 
BEGIN 
dbms_session.set_nls('NLS_DATE_FORMAT','''DD-MON-YYYY'''); 
l_parser := dbms_xmlparser.newParser; 
dbms_xmlparser.parseClob(l_parser, p_clob); 
l_doc := dbms_xmlparser.getDocument(l_parser); 
dbms_xmlparser.freeParser(l_parser); 

... 

dbms_xmldom.freeDocument(l_doc); 
EXCEPTION 
WHEN OTHERS THEN 
dbms_xmlparser.freeParser(l_parser); 
dbms_xmldom.freeDocument(l_doc); 
END; 
/

,並調用它像:

DECLARE 
l_clob clob; 
BEGIN 
l_clob := '<TWObject className="TWObject"> 
    <array size="240"> 
    ... 
</array> 
</TWOject>'; 

parse_xml_data(l_clob); 
END; 
/

如果字符串超過32K那麼您需要通過將其附加到塊中來構建CLOB;但在這種情況下,無論如何它可能是simoler從文件加載。

你也可以讓你當前的過程成爲這個過程的包裝 - 使它從文件中加載CLOB,然後將它傳遞給新函數,所以你沒有複製語法邏輯。