1、PLSQL解析XML使用PL/SQL程序如何解析XML(原创)学习篇-XML文件解析文档作者: Siman.He MSN : *创建日期: 2009-5-22更新日期: 2009-5-22文档编号: 当前版本: Draft 1.0Note:Title, Subject, Last Updated Date, Reference Number, and Version are marked by a Word Bookmark so that they can be easily reproduced in the header and footer of documents. When you
2、 change any of these values, be careful not to accidentally delete the bookmark. You can make bookmarks visible by selecting Tools-OptionsView and checking the Bookmarks option in the Show region.文档控制变更记录日期作者版本变更说明07/04/08IBM1.0初版审阅姓名职位分发拷贝编号姓名位置/岗位1资料室主管项目资料室2项目组成员34Note:The copy numbers referenced
3、 above should be written into the Copy Number space on the cover of each distributed copy. If the document is not controlled, you can delete this table, the Note To Holders, and the Copy Number label from the cover page.Note:To update the table of contents, put the cursor anywhere in the table and p
4、ress F9. To change the number of levels displayed, select the menu option InsertIndex and Tables, make sure the Table of Contents tab is active, and change the Number of Levels to a new value.概述使用XML文件传输数据,现在已经被越来越多的项目所采纳。其做法通常是用额外开发的java 程序来解析XML数据。其实Oracle已经为XML配备了一套功能健全的工具集,该工具集允许PL/SQL和Java开发人员在
5、Oracle数据库内部进行工作。本文简要地概述了XML特性和适用于Oracle数据库的实用程序,描述如何设置并使用面向XML的Oracle PL/SQL分析程序,然后介绍了一个实例程序,该程序分析PL/SQL内的XML信息。XML组建在PL/SQL中利用XML ,Oracle提供了几个组件,让开发人员能轻松地利用XML技术。这些组件包括: 1. XML 分析程序。即用来分析、构造和验证XML文档。. 2. XPath 引擎。 它是使用Xpath(XML标准的另一个元素)说明语法在内存中搜索XML文档的实用程序。 SLT 处理器。 它在Oracle数据库中支持XSLT,允许您把XML文档转换成其
6、他格式。 3. XML SQL 实用程序。可以使用SQL产生XML文档,使您可以在Oracle数据库表格中轻松地插入基于XML的数据。 XSQL 页。一项可以汇集声明性XML数据然后通过XSLT公布这些数据的技术。 对于PL/SQL开发人员而言,XML分析程序是最重要的组件。通过它,您可以在Oracle数据库中分析、操纵和转换XML文档。ML分析程序由一套APIs(应用程序编程接口)构成。XML结构图XML常用的分析函数XMLParser包括分析XML文档所需的数据类型和程序。XML Parsing Process想知道Oracle的parser是如何调用Java来做解析的,请查看Oracle
7、 XML Developers Kit Programmers Guide10g Release 2 (10.2)Part Number B14252-01网址: 程序中常用的方法:Nodelist := dbms_xslprocessor.selectnodes(rootnode, xpath) dbms_xslprocessor.valueof(节点,节点下的元素,值) 具体的实例,会在下面讲解。XMLDOM 包括管理和建立XML文档对象模型(DOM)元素所需的数据类型和程序Comparing DOM (Tree-Based) and SAX (Event-Based) APIsXMLDO
8、M 这个程序包,其实是通过封装Java 程序来解析XML 的一个PL/SQL的包。具体的作用还是要参考Oracle Database PL/SQL Packages and Types Reference10g Release 2 (10.2)Part Number B14258-02网址: XML解析实例案列: XML文件 :simanhe_test.xml2001 测试1 滘滘生僻字 测试2 看一看 测试3 瞅一瞅 测试4 试一试 测试5 爽一爽 文件的结构解析方案在XML DOM的解析过程中, 如果想找某个节点(Fitem)的属性(RecErrCode),而该节点又不是根节点时,需要从最
9、小的节点往上找父节点,一直到节点Fitem,然后在得到其属性。如果节点是根节点,则可以直接得到根节点的元素和属性的值。根据上图所示,我们要找根节点Dfile的元素和属性的值,直接调用 。XML解析脚本 Oracle通过调用API xmldom和dbms_xmlparser来做XML文件的解析。.建立一个 Directory ,假如在EBS上实现则需要在EBS DB的服务器上建立路径如: Create Or Replace Directory FTP_XXX As /var/tmp/ftp 直接在APPS下就可以新建要查找当前建立的Directory 可以使用 Select * From all
10、_directories 查找当前系统中的所有的 Directory . 2.代码如下 DECLARE p_max_size NUMBER := dbms_lob.lobmaxsize; src_offset NUMBER := 1; dst_offset NUMBER := 1; lang_ctx NUMBER := nls_charset_id(UTF8); default_csid CONSTANT INTEGER := nls_charset_id(ZHS16GBK); warning NUMBER; l_file_number PLS_INTEGER := 0; l_count NU
11、MBER; l_bfile BFILE; l_clob CLOB; l_commitelement xmldom.domelement; l_parser dbms_xmlparser.parser; l_doc dbms_xmldom.domdocument; l_nl dbms_xmldom.domnodelist; l_n dbms_xmldom.domnode; rootnode dbms_xmldom.domnode; parent_rootnode dbms_xmldom.domnode; file_length NUMBER; block_size BINARY_INTEGER;
12、 l_rootnode_name VARCHAR2(200); l_status VARCHAR2(1000); l_recerrcode VARCHAR2(1000); l_FailCount VARCHAR2(200); l_RecCount VARCHAR2(200); l_name VARCHAR2(1000); l_comments VARCHAR2(2000); l_exists BOOLEAN; FUNCTION convertclobtoxmlelement(p_document IN CLOB) RETURN xmldom.domelement IS x_commitelem
13、ent xmldom.domelement; l_parser xmlparser.parser; BEGIN l_parser := xmlparser.newparser; xmlparser.parseclob(l_parser, p_document); x_commitelement := xmldom.getdocumentelement(xmlparser.getdocument(l_parser); RETURN x_commitelement; END convertclobtoxmlelement;BEGIN - 检查XML是否在路径FTP_XXX下是否存在 utl_fil
14、e.fgetattr(FTP_XXX, simanhe_test.xml, l_exists, file_length, block_size); IF NOT l_exists THEN dbms_output.put_line(XML文件不存在); RETURN; END IF; l_bfile := bfilename(FTP_XXX, simanhe_test.xml); - 创建一个Clob dbms_lob.createtemporary(l_clob, TRUE); dbms_lob.OPEN(l_bfile, dbms_lob.lob_readonly); - 将XML文件上载
15、并转换为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); IF l_file_number = 0 THEN dbms_output.put_line(XML文件未被转换成功); RETURN; END IF; dbms_lob.CLOSE(l_bfile); - Create a par
16、ser. l_parser := dbms_xmlparser.newparser; BEGIN - Parse the document and create a new DOM document. dbms_xmlparser.parseclob(l_parser, l_clob); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(XML文件不完整); RETURN; END; l_doc := dbms_xmlparser.getdocument(l_parser); - Free resources associated with the
17、 CLOB and Parser now they are no longer needed. dbms_lob.freetemporary(l_clob); - 得到根节点 rootnode := xmldom.makenode(xmldom.getdocumentelement(xmlparser.getdocument(l_parser); l_rootnode_name := xmldom.getnodename(rootnode); dbms_output.put_line(XML文件当前的节点名称为 | l_rootnode_name); - 得到根节点元素的值 dbms_xslp
18、rocessor.valueof(rootnode, RecCount/text(), l_RecCount); dbms_xslprocessor.valueof(rootnode, FailCount/text(), l_FailCount); dbms_output.put_line(XML文件当前的节点名称为 | l_rootnode_name | 的要素RecCount,FailCount值为 | l_RecCount|,|l_FailCount); - 得到根节点Dfile的属性Status的值 l_status := xmldom.getattribute(xmldom.make
19、element(rootnode), Status); dbms_output.put_line(XML文件当前的节点名称为 | l_rootnode_name | 的属性Status的值为 | l_status); /*取节点Item下各元素的值,先将Items节点全部存放在 l_nl中 */ l_nl := dbms_xmldom.getelementsbytagname(l_doc, Item); l_count := dbms_xmldom.getlength(l_nl); FOR cur_emp IN 0 . dbms_xmldom.getlength(l_nl) - 1 LOOP
20、l_n := dbms_xmldom.item(l_nl, cur_emp); - 得到节点Item下元素的值 dbms_xslprocessor.valueof(l_n, Name/text(), l_name); dbms_xslprocessor.valueof(l_n, Comment/text(), l_comments); - 得到节点Item的父节点FItem parent_rootnode := dbms_xmldom.getparentnode(l_n); l_rootnode_name := xmldom.getnodename(parent_rootnode); - 得到
21、节点FItem的属性RecErrCode的值 l_recerrcode := xmldom.getattribute(xmldom.makeelement(parent_rootnode), RecErrCode); dbms_output.put_line(Name : | l_name | ,Comment = | l_comments | ,RecErrCode = | l_recerrcode); END LOOP; - 释放分析函数的资源 dbms_xmlparser.freeparser(l_parser); - 将DOC清空,释放资源 dbms_xmldom.freedocume
22、nt(l_doc); /* utl_file.frename(FTP_XXX, simanhe_test.xml, FTP_XXX, D_simanhe_test.xml, FALSE);*/ - XML文件解析完成后重命名 /*utl_file.fremove(FTP_XXX, simanhe_test.xml); */ - - XML文件解析完成后删除文件EXCEPTION WHEN OTHERS THEN dbms_lob.freetemporary(l_clob); dbms_xmlparser.freeparser(l_parser); dbms_xmldom.freedocument(l_doc);END;以上程序经测试是可以正常运行的。但是对XML文件的大小有要求,最好不要超过10M。文件的个头越大解析的效率会越差。我一般建议XML文件大小为2M左右,另外对一些生僻字我在上载XML文件的时候就已经将其转化为ZHS16GBK了,所以不存在乱码的问题。以上的脚本可以给大家提供一个参考,希望能对大伙有所帮助。更改历史
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1