PLSQL解析XML文档格式.docx
《PLSQL解析XML文档格式.docx》由会员分享,可在线阅读,更多相关《PLSQL解析XML文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
姓名
职位
分发
拷贝编号
位置/岗位
1
资料室主管
项目资料室
2
项目组成员
3
4
ThecopynumbersreferencedaboveshouldbewrittenintotheCopyNumberspaceonthecoverofeachdistributedcopy.Ifthedocumentisnotcontrolled,youcandeletethistable,theNoteToHolders,andtheCopyNumberlabelfromthecoverpage.
Toupdatethetableofcontents,putthecursoranywhereinthetableandpress[F9].Tochangethenumberoflevelsdisplayed,selectthemenuoptionInsert>
IndexandTables,makesuretheTableofContentstabisactive,andchangetheNumberofLevelstoanewvalue.
概述
使用XML文件传输数据,现在已经被越来越多的项目所采纳。
其做法通常是用额外开发的java程序来解析XML数据。
其实Oracle已经为XML配备了一套功能健全的工具集,该工具集允许PL/SQL和Java开发人员在Oracle数据库内部进行工作。
本文简要地概述了XML特性和适用于Oracle数据库的实用程序,描述如何设置并使用面向XML的OraclePL/SQL分析程序,然后介绍了一个实例程序,该程序分析PL/SQL内的XML信息。
XML组建
在PL/SQL中利用XML,Oracle提供了几个组件,让开发人员能轻松地利用XML技术。
这些组件包括:
1.XML分析程序。
即用来分析、构造和验证XML文档。
.
2.XPath引擎。
它是使用Xpath(XML标准的另一个元素)说明语法在内存中搜索XML文档的实用程序。
SLT处理器。
它在Oracle数据库中支持XSLT,允许您把XML文档转换成其他格式。
3.XMLSQL实用程序。
可以使用SQL产生XML文档,使您可以在Oracle数据库表格中轻松地插入基于XML的数据。
XSQL页。
一项可以汇集声明性XML数据然后通过XSLT公布这些数据的技术。
对于PL/SQL开发人员而言,XML分析程序是最重要的组件。
通过它,您可以在Oracle数据库中分析、操纵和转换XML文档。
ML分析程序由一套APIs(应用程序编程接口)构成。
XML结构图
XML常用的分析函数
XMLParser
包括分析XML文档所需的数据类型和程序。
XMLParsingProcess
想知道Oracle的parser是如何调用Java来做解析的,请查看Oracle®
XMLDeveloper'
sKitProgrammer'
sGuide
10gRelease2(10.2)
PartNumberB14252-01
网址:
程序中常用的方法:
Nodelist:
=dbms_xslprocessor.selectnodes(rootnode,xpath)
dbms_xslprocessor.valueof(节点,节点下的元素,值)
具体的实例,会在下面讲解。
XMLDOM
包括管理和建立XML文档对象模型(DOM)元素所需的数据类型和程序
ComparingDOM(Tree-Based)andSAX(Event-Based)APIs
XMLDOM这个程序包,其实是通过封装Java程序来解析XML的一个PL/SQL的包。
具体的作用还是要参考Oracle®
DatabasePL/SQLPackagesandTypesReference
PartNumberB14258-02
XML解析实例
案列:
XML文件:
simanhe_test.xml
<
?
xmlversion="
1.0"
encoding="
UTF-8"
>
DfileStatus="
3"
RecCount>
200<
/RecCount>
FailCount>
1<
/FailCount>
FailInfo>
FItemRecErrCode="
2901"
Item>
Name>
测试1<
/Name>
Comment>
滘滘生僻字<
/Comment>
/Item>
测试2<
看一看<
/FItem>
/FailInfo>
2902"
测试3<
瞅一瞅<
测试4<
试一试<
测试5<
爽一爽<
文件的结构
解析方案
在XMLDOM的解析过程中,如果想找某个节点(Fitem)的属性(RecErrCode),而该节点又不是根节点时,需要从最小的节点往上找父节点,一直到节点Fitem,然后在得到其属性。
如果节点是根节点,则可以直接得到根节点的元素和属性的值。
根据上图所示,我们要找根节点Dfile的元素和属性的值,直接调用。
XML解析脚本
Oracle通过调用APIxmldom和dbms_xmlparser来做XML文件的解析。
1. 建立一个Directory,假如在EBS上实现则需要在EBSDB的服务器上建立路径 如:
CreateOrReplaceDirectoryFTP_XXXAs'
/var/tmp/ftp'
直接在APPS下就可以新建
要查找当前建立的Directory可以使用Select*Fromall_directories查找当前系统中的所有的Directory.
2.代码如下
DECLARE
p_max_sizeNUMBER:
=dbms_lob.lobmaxsize;
src_offsetNUMBER:
=1;
dst_offsetNUMBER:
lang_ctxNUMBER:
=nls_charset_id('
UTF8'
);
default_csidCONSTANTINTEGER:
ZHS16GBK'
warningNUMBER;
l_file_numberPLS_INTEGER:
=0;
l_countNUMBER;
l_bfileBFILE;
l_clobCLOB;
l_commitelementxmldom.domelement;
l_parserdbms_xmlparser.parser;
l_docdbms_xmldom.domdocument;
l_nldbms_xmldom.domnodelist;
l_ndbms_xmldom.domnode;
rootnodedbms_xmldom.domnode;
parent_rootnodedbms_xmldom.domnode;
file_lengthNUMBER;
block_sizeBINARY_INTEGER;
l_rootnode_nameVARCHAR2(200);
l_statusVARCHAR2(1000);
l_recerrcodeVARCHAR2(1000);
l_FailCountVARCHAR2(200);
l_RecCountVARCHAR2(200);
l_nameVARCHAR2(1000);
l_commentsVARCHAR2(2000);
l_existsBOOLEAN;
FUNCTIONconvertclobtoxmlelement(p_documentINCLOB)
RETURNxmldom.domelementIS
x_commitelementxmldom.domelement;
l_parserxmlparser.parser;
BEGIN
l_parser:
=xmlparser.newparser;
xmlparser.parseclob(l_parser,p_document);
x_commitelement:
=xmldom.getdocumentelement(xmlparser.getdocument(l_parser));
RETURNx_commitelement;
ENDconvertclobtoxmlelement;
BEGIN
--检查XML是否在路径FTP_XXX下是否存在
utl_file.fgetattr('
FTP_XXX'
'
simanhe_test.xml'
l_exists,
file_length,
block_size);
IFNOTl_existsTHEN
dbms_output.put_line('
XML文件不存在'
RETURN;
ENDIF;
l_bfile:
=bfilename('
'
--创建一个Clob
dbms_lob.createtemporary(l_clob,TRUE);
dbms_lob.OPEN(l_bfile,dbms_lob.lob_readonly);
--将XML文件上载并转换为Clob类型
dbms_lob.loadclobfromfile(l_clob,
l_bfile,
p_max_size,
dst_offset,
src_offset,
default_csid,--UTF8
lang_ctx,--GBK
warning);
l_file_number:
=dbms_lob.fileexists(l_bfile);
IFl_file_number=0THEN
XML文件未被转换成功'
dbms_lob.CLOSE(l_bfile);
--Createaparser.
=dbms_xmlparser.newparser;
--ParsethedocumentandcreateanewDOMdocument.
dbms_xmlparser.parseclob(l_parser,l_clob);
EXCEPTION
WHENOTHERSTHEN
XML文件不完整'
END;
l_doc:
=dbms_xmlparser.getdocument(l_parser);
--FreeresourcesassociatedwiththeCLOBandParsernowtheyarenolongerneeded.
dbms_lob.freetemporary(l_clob);
--得到根节点
rootnode:
=xmldom.makenode(xmldom.getdocumentelement(xmlparser.getdocument(l_parser)));
l_rootnode_name:
=xmldom.getnodename(rootnode);
XML文件当前的节点名称为'
||l_rootnode_name);
--得到根节点元素的值
dbms_xslprocessor.valueof(rootnode,'
RecCount/text()'
l_RecCount);
FailCount/text()'
l_FailCount);
||l_rootnode_name||
的要素RecCount,FailCount值为'
||l_RecCount||'
'
||l_FailCount);
--得到根节点Dfile的属性Status的值
l_status:
=xmldom.getattribute(xmldom.makeelement(rootnode),'
Status'
的属性Status的值为'
||l_status);
/*取节点Item下各元素的值,先将Items节点全部存放在l_nl中*/
l_nl:
=dbms_xmldom.getelementsbytagname(l_doc,'
Item'
l_count:
=dbms_xmldom.getlength(l_nl);
FORcur_empIN0..dbms_xmldom.getlength(l_nl)-1LOOP
l_n:
=dbms_xmldom.item(l_nl,cur_emp);
--得到节点Item下元素的值
dbms_xslprocessor.valueof(l_n,'
Name/text()'
l_name);
Comment/text()'
l_comments);
--得到节点Item的父节点FItem
parent_rootnode:
=dbms_xmldom.getparentnode(l_n);
=xmldom.getnodename(parent_rootnode);
--得到节点FItem的属性RecErrCode的值
l_recerrcode:
=xmldom.getattribute(xmldom.makeelement(parent_rootnode),
RecErrCode'
Name:
'
||l_name||'
Comment='
||
l_comments||'
RecErrCode='
||l_recerrcode);
ENDLOOP;
--释放分析函数的资源
dbms_xmlparser.freeparser(l_parser);
--将DOC清空,释放资源
dbms_xmldom.freedocument(l_doc);
/*utl_file.frename('
D_simanhe_test.xml'
FALSE);
*/--XML文件解析完成后重命名
/*utl_file.fremove('
*/----XML文件解析完成后删除文件
EXCEPTION
END;
以上程序经测试是可以正常运行的。
但是对XML文件的大小有要求,最好不要超过10M。
文件的个头越大解析的效率会越差。
我一般建议XML文件大小为2M左右,另外对一些生僻字我在上载XML文件的时候就已经将其转化为ZHS16GBK了,所以不存在乱码的问题。
以上的脚本可以给大家提供一个参考,希望能对大伙有所帮助。
更改历史