解析XML文件

来源:互联网 发布:淘宝金牌卖家有假货吗 编辑:程序博客网 时间:2024/05/21 20:23

参考:http://blog.csdn.net/cai_xingyun/article/details/18225427

PL/SQL中利用XML ,Oracle提供了几个组件,让开发人员能轻松地利用XML技术。这些组件包括:

 1. XML 分析程序。即用来分析、构造和验证XML文档。.

2. XPath引擎。它是使用XpathXML标准的另一个元素)说明语法在内存中搜索XML文档的实用程序。 SLT 处理器。它在Oracle数据库中支持XSLT,允许您把XML文档转换成其他格式。

3. XML SQL实用程序。可以使用SQL产生XML文档,使您可以在Oracle数据库表格中轻松地插入基于XML的数据。 XSQL 页。一项可以汇集声明性XML数据然后通过XSLT公布这些数据的技术。对于PL/SQL开发人员而言,XML分析程序是最重要的组件。通过它,您可以在Oracle数据库中分析、操纵和转换XML文档。ML分析程序由一套APIs(应用程序编程接口)构成。


XML结构

 


XML常用分析函数


XMLParser


包括分析XML文档所需的数据类型和程序。XML Parsing Process


 

想知道Oracleparser是如何调用Java来做解析的,请查看Oracle® XMLDeveloper's Kit Programmer's Guide
10g Release 2 (10.2)

Part Number B14252-01

网址:http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14252/adx_j_parser.htm#i1013320

程序中常用的方法:

Nodelist := dbms_xslprocessor.selectnodesrootnode, xpath

dbms_xslprocessor.valueof(节点,节点下的元素,)


XMLDOM


包括管理和建立XML文档对象模型(DOM)元素所需的数据类型和程序

Comparing DOM (Tree-Based) and SAX (Event-Based) APIs

XMLDOM这个程序包,其实是通过封装Java程序来解析XML的一个PL/SQL的包。具体的作用还是要参考Oracle® Database PL/SQLPackages and Types Reference
10g Release 2 (10.2)

Part Number B14258-02

网址:http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_xmldom.htm


实例

<?xml version="1.0" encoding="UTF-8"?><Dfile Status="3"><RecCount>200</RecCount><FailCount>1</FailCount> <FailInfo>  <FItem RecErrCode="2901">     <Item>       <Name>名称1</Name>       <Comment>中国银行</Comment>     </Item>     <Item>       <Name>名称2</Name>       <Comment>建设银行</Comment>     </Item>  </FItem> </FailInfo> <FailInfo>  <FItem RecErrCode="2902">     <Item>       <Name>名称3</Name>       <Comment>招商银行</Comment>     </Item>     <Item>       <Name>名称4</Name>       <Comment>平安银行</Comment>     </Item>     <Item>       <Name>名称5</Name>       <Comment>工商银行</Comment>     </Item>  </FItem> </FailInfo>


 


文件的结构



解析方案


 

XML DOM的解析过程中,如果想找某个节点(Fitem)的属性(RecErrCode),而该节点又不是根节点时,需要从最小的节点往上找父节点,一直到节点Fitem,然后在得到其属性。如果节点是根节点,则可以直接得到根节点的元素和属性的值。

根据上图所示,我们要找根节点Dfile的元素和属性的值,直接调用


Oracle通过调用APIxmldomdbms_xmlparser来做XML文件的解析。


. 建立一个Directory,假如在EBS上实现则需要在EBS DB的服务器上建立路径 如:


 CreateOr Replace Directory FTP_XXX As '/var/tmp/ftp'直接在APPS下就可以新建


要查找当前建立的Directory可以使用Select *From all_directories查找当前系统中的所有的Directory .

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         NUMBER;  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;  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_commitelement 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_file.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文件上载并转换为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 parser.  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 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_xslprocessor.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.makeelement(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    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);    -- 得到节点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.freedocument(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;


 

 

0 0