zoukankan      html  css  js  c++  java
  • PLSQL解析XML文件

    

    参考网上资料学习汇总

    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通过调用API xmldomdbms_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;
    







  • 相关阅读:
    2011 年50+优秀的网页设计(下)
    25+令人惊讶的是令人难以置信的WordPress技术支持网站
    2011 漂亮的网站(上)
    2011 美丽的网站(下)
    38 jQuery和CSS多级下拉菜单解决方案(一)
    HTMl代码片段
    30 +漂亮的jQuery菜单导航(一)
    分享几套还算不错的后台模板(有源码下载)
    配 色 方 案
    一个小故事
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299346.html
Copyright © 2011-2022 走看看