我收到一个我需要在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文件解析为
的oracle过程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 :(得分:0)
如果字符串小于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来构建CLOB;但在这种情况下,无论如何都可以从文件中加载。
你也可以让你当前的程序成为这个程序的包装 - 让它从文件加载CLOB,然后将它传递给新函数,这样你就不会复制解析逻辑。