Oracle操作XML各种场景介绍

版权声明:凭栏处。潇潇雨歇。 https://blog.csdn.net/IndexMan/article/details/28130961

近期在研究Oracle PLSQL中对于XML的系列操作。结合工作中使用的知识和參考资料整理出以下相关内容:

一 怎样生成XML文件:

1、使用dbms_xmlquery和utl_file内置包(scott用户运行)

CREATE OR REPLACE DIRECTORY xml_dir AS ‘d:\app\xml‘;

DROP SEQUENCE seq_filename;
CREATE SEQUENCE seq_filename
    MINVALUE 10000
    MAXVALUE 99999
    INCREMENT BY 1
    START WITH 10000
    NOCYCLE;

DECLARE
    v_filename  Varchar2(50)  := ‘Empmsg‘||to_char(seq_filename.nextval)||‘.xml‘;
    xml_str     clob;
    xml_file    utl_file.file_type;
    offset      number;
    buffer      varchar2(32767);
    buffer_size number;
BEGIN
    offset      := 1;
    buffer_size := 3000;
    xml_file := utl_file.fopen(‘XML_DIR‘, v_filename, ‘w‘);
    xml_str  := dbms_xmlquery.getxml(‘select empno,
                                             ename,
                                             job,
                                             mgr,
                                             hiredate,
                                             sal,
                                             comm,
                                             deptno
                                      from emp‘);

    while (offset < dbms_lob.getlength(xml_str)) loop
      buffer := dbms_lob.substr(xml_str, buffer_size, offset);
      utl_file.put(xml_file, buffer);
      utl_file.fflush(xml_file);
      offset := offset + buffer_size;
    end loop;

    utl_file.fclose(xml_file);
END;

? ? ? ? 2、使用XMLELEMENT系列内置函数返回xml(sys用户运行)

DECLARE
    v_filename  Varchar2(50)  := ‘Empmsg‘||to_char(scott.seq_filename.nextval)||‘.xml‘;
    xml_str     clob;
    xml_file    utl_file.file_type;
    offset      number;
    buffer      varchar2(32767);
    buffer_size number;
BEGIN
    offset      := 1;
    buffer_size := 3000;
    xml_file := utl_file.fopen(‘XML_DIR‘, v_filename, ‘w‘);
    SELECT XMLElement("DEPARTMENT"
                 , XMLAttributes( department_id as "ID"
                                , department_name as "NAME"
                                )
                 , XMLElement("EMPLOYEES"
                             , (SELECT XMLAgg( XMLElement("EMPLOYEE"
                                                         , XMLForest(employee_id as "ID"
                                                                    ,first_name||‘ ‘||last_name as "NAME"
                                                                    )
                                                         )
                                             )
                                 FROM hr.employees emp
                                WHERE emp.department_id = dept.department_id
                                )
                              )
                ).getclobval() INTO xml_str
     FROM hr.departments dept
     WHERE department_id = 20;

    while (offset < dbms_lob.getlength(xml_str)) loop
      buffer := dbms_lob.substr(xml_str, buffer_size, offset);
      utl_file.put(xml_file, buffer);
      utl_file.fflush(xml_file);
      offset := offset + buffer_size;
    end loop;

    utl_file.fclose(xml_file);
END;

--XMLElement: 将一个关系值转换为XML元素的函数。格式为<elementName>值</elementName>?
--XMLAttributes: 用于在SQL查询返回的 XML 元素中设置属性的函数?
--XMLForest: ? ? ?该函数返回一个或多个子元素的集合,该函数使用列名做为XML元素的名称并用SQL值表达式做为XML元素的内容。但使用时不能指定元素的属性?
--XMLAgg: ? ? ? ? ? 在GROUP BY查询中对XML数据进行分组或汇总的函数?

PS: 使用SPOOL方式导出文件:

SET TRIMSPOOL ON
SET TERMOUT ON
SET FEEDBACK OFF
SET VERIFY OFF
SET ECHO OFF
SET PAGESIZE 999
SET HEAD OFF
SET HEADING OFF
SET LONG 5000
spool c:\a.xml
SELECT XMLElement("DEPARTMENT"
                 , XMLAttributes( department_id as "ID"
                                , department_name as "NAME"
                                )
                 , XMLElement("EMPLOYEES"
                             , (SELECT XMLAgg( XMLElement("EMPLOYEE"
                                                         , XMLForest(employee_id as "ID"
                                                                    ,first_name||‘ ‘||last_name as "NAME"
                                                                    )
                                                         )
                                             )
                                 FROM employees emp
                                WHERE emp.department_id = dept.department_id
                                )
                              )
                ) a
  FROM departments dept
 WHERE department_id = 10;
spool off

二 怎样存储XML文件内容:

我们知道oracle 中xmltype数据类型用来存储XML内容。

以下样例中介绍怎样将系统中XML文件内容载入至

含有XMLTYPE类型的表中。

CREATE TABLE xml_table OF XMLTYPE;

INSERT INTO xml_table
    VALUES(XMLTYPE(bfilename(‘XML_DIR‘,‘PurchaseOrder.xml‘),nls_charset_id(‘AL32UTF8‘)));

    SELECT x.sys_nc_rowinfo$.getstringval() FROM xml_table x;

CREATE TABLE table_with_xml_column(filename VARCHAR2(64), xml_document XMLTYPE);

INSERT INTO table_with_xml_column
    VALUES (‘PurchaseOrder.xml‘,XMLType(bfilename(‘XML_DIR‘, ‘PurchaseOrder.xml‘),nls_charset_id(‘AL32UTF8‘)));

SELECT x.xml_document.getCLOBVal() FROM table_with_xml_column x;

PurchaseOrder.xml内容:

<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation=
    "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd">
  <Reference>SBELL-2002100912333601PDT</Reference>
  <Actions>
    <Action>
      <User>SVOLLMAN</User>
    </Action>
  </Actions>
  <Reject/>
  <Requestor>Sarah J. Bell</Requestor>
  <User>SBELL</User>
  <CostCenter>S30</CostCenter>
  <ShippingInstructions>
    <name>Sarah J. Bell</name>
    <address>400 Oracle Parkway
      Redwood Shores
      CA
      94065
      USA</address>
    <telephone>650 506 7400</telephone>
  </ShippingInstructions>
  <SpecialInstructions>Air Mail</SpecialInstructions>
  <LineItems>
    <LineItem ItemNumber="1">
      <Description>A Night to Remember</Description>
      <Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
    </LineItem>
    <LineItem ItemNumber="2">
      <Description>The Unbearable Lightness Of Being</Description>
      <Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
    </LineItem>
    <LineItem ItemNumber="3">
      <Description>Sisters</Description>
      <Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
    </LineItem>
  </LineItems>
</PurchaseOrder>

三 怎样解析XML内容:

?1、XPath结构介绍:

? ??

? ? ? ? ?/ ? ? ? 表示树根。

比如:/PO 指向树根的子节点<PO>; 通常也作为路径分隔符使用,比如:/A/B

? ? ? ? //
表示当前节点下全部子节点;比如:/A//B 匹配A节点下全部B节点

? ? ? ? * ? ? ? 作为通配符使用,匹配全部子节点; 如:/A/*/C 匹配A节点下全部子节点C

? ? ? ? [ ] ? ? ?表示预期表达式;XPath支持丰富的操作符如OR、AND、NOT等;比如:/PO[PONO=20 AND PNAME="PO_2"]/SHIPADDR 匹配全部订单号为20而且订单名为PO_2的送货地址

@?用来提取节点属性

? ? ? ? FunctionsXPath支持一些内置函数如:substring(), round() 和 not().?

? ? ? 2、使用XMLTYPE方法查询XML:

? ? ? ? ? ??SELECT x.OBJECT_VALUE.getCLOBVal() FROM xml_table x;

? ? ? ? ? ? ?SELECT x.OBJECT_VALUE.getSTRINGVal() FROM xml_table x;

? ? ? 3、使用函数解析XML:

--existsNode 推断XPath中节点是否存在,存在返回值1 不存在返回0;

SELECT existsNode(OBJECT_VALUE, ‘/PurchaseOrder/Reference‘)
FROM purchaseorder;

--extractValue ?提取XPath节点值

SELECT extractValue(OBJECT_VALUE, ‘/PurchaseOrder/Reference‘)
FROM purchaseorder
WHERE existsNode(OBJECT_VALUE, ‘/PurchaseOrder/Reference‘) = 1;

--extract ? 提取XPath节点

SELECT extract(OBJECT_VALUE, ‘/PurchaseOrder/Reference‘) "REFERENCE"
FROM purchaseorder;

4、使用SQL解析XML:

SELECT extractValue(OBJECT_VALUE, ‘/PurchaseOrder/Reference‘) REFERENCE,
    extractValue(OBJECT_VALUE, ‘/PurchaseOrder/*//User‘) USERID,
    CASE
        WHEN existsNode(OBJECT_VALUE, ‘/PurchaseOrder/Reject‘) = 1
        THEN ‘Rejected‘
        ELSE ‘Accepted‘
    END "STATUS",
extractValue(OBJECT_VALUE, ‘//CostCenter‘) CostCenter
FROM purchaseorder
WHERE existsNode(OBJECT_VALUE,‘//Reject‘) = 1;

四 ? XMLTABLE使用方法:

XMLTable?maps the result of an XQuery evaluation into
relational rows and columns. You can query the result returned by the function as a virtual relational table using SQL.

说白了就是解析XML内容返回虚拟关系型结构数据。 以下说个简单样例:

? ? ? ??

? ? ? ??

CREATE TABLE warehouses(
	warehouse_id NUMBER(3),
	warehouse_spec SYS.XMLTYPE,
	warehouse_name VARCHAR2(35),
location_id NUMBER(4)
);

INSERT into warehouses (warehouse_id, warehouse_spec,warehouse_name) VALUES (100, sys.XMLType.createXML(

‘<Warehouse whNo="100">
   <opt1>
        <Building>Owned</Building>
        <WaterAccess>WaterAccess</WaterAccess>
        <RailAccess>RailAccess</RailAccess>
        <field>f1</field>
        <field>f2</field>
        <field>f3</field>
   </opt1>
   <opt2>
        <name>Dylan</name>
   </opt2>
</Warehouse>‘),‘Warehouse-X‘);	

SELECT warehouse_name warehouse,
   warehouse2."whNo"
FROM warehouses,
   XMLTABLE(‘/Warehouse‘
      PASSING warehouses.warehouse_spec
      COLUMNS
         "whNo" varchar2(100) PATH ‘@whNo‘)
      warehouse2;

SELECT warehouse_name warehouse,
   warehouse2."Water", warehouse2."Rail", warehouse2.field
   FROM warehouses,
   XMLTABLE(‘*//opt1‘
      PASSING warehouses.warehouse_spec
      COLUMNS
         "Water" varchar2(100) PATH ‘//WaterAccess‘,
         "Rail" varchar2(100) PATH ‘//RailAccess‘,
         field XMLTYPE PATH ‘/‘)
      warehouse2;

? ? 具体文章链接:?http://viralpatel.net/blogs/oracle-xmltable-tutorial/

to be continue...

----------------------------------

By ? ?Dylan.

原文地址:https://www.cnblogs.com/ldxsuanfa/p/10472848.html

时间: 2024-11-02 12:10:06

Oracle操作XML各种场景介绍的相关文章

廖雪峰Java14Java操作XML和JSON-2JSON-1Json介绍

JSON是一种类似JavaScript对象的数据表示格式 JavaScript Object Notation 去除了JavaScript的执行语句 仅保留数据 JSON格式: 仅保留UTF-8编码 必须使用双引号 特殊字符用\转译 "abc\nxyz\tend" JSON特点: 适合表示层次结构 格式简单.仅支持 * {..} 键值对 * [...] 数组 * String字符串 * Number数值(整数和浮点数) * Boolean 布尔值 * null空值 { "co

详细介绍Flex中操作XML

一  在介绍Flex中操作XML之前,首先简单介绍下XML中的基本术语. 元素:XML中拥有开始标签和结束标签的这一块称为“元素”    节点:把XML元素与文本结合起来统称为节点    根节点:位于整个XML文当顶端的节点    文本节点:包含文本的节点    属性:元素的组成部分,以键/值形式放在元素标签内 用一个例子来说明 <root_node><!--这是一个根节点也是一个元素--> <node attribute="value"><!

转载:用Ant操作XML文件

1.14 用XMLTask操作XML(1) 本节作者:Brian Agnew 对于简单的文本搜索和替换操作,Ant的<replace>任务就够用了,但在现代Java框架中,用户更可能需要强大的XML操作能力来修改servlet描述符.Spring配置等. XMLTask是Ant外部任务,它提供了强大的XML编辑工具,主要用于在构建/部署过程中创建和修改XML文件. 使用XMLTask的好处如下? 与Ant的<replace>任务不同,XMLTask使用XPath提供识别XML文档各

Winform开发框架里面使用事务操作的原理及介绍

在很多情况下,事务是个很有用的东西,可以把一系列的操作组合成一个原子粒度的操作,一旦组合中某个地方出错,可以整个干净的进行滚回,不会留下脏数据:除此之外,事务还能提高批量操作的效率,如在本地SQLite数据库里面,批量插入1万条数据,那么使用事务和没有使用事务,速度上至少差别几十到上百倍的差异.既然事务有完整性和速度性的差异,因此,基于上述原因,我们在很多情况下最好使用事务进行操作.本文主要介绍在开发框架中如何整合事务的操作,并介绍在各个分层中的事务使用案例. 由于我介绍的相关框架,主要是采用了

Redis 中 5 种数据结构的使用场景介绍

这篇文章主要介绍了Redis中5种数据结构的使用场景介绍,本文对Redis中的5种数据类型String.Hash.List.Set.Sorted Set做了讲解,需要的朋友可以参考下 一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 redis 中一共有5种数据结构,那每种数据结构的使用场景都是什么呢? String——字符串 Hash——字典

简单操作XML

第一部分 什么是XML? XML, Extensible Markup Language ,可扩展标记语言,主要用途是描述和交换数据.它的一个用处是配置文件,用来保存数据库连接字符串.端口.IP.日志保存路径等参数.我们可以使用文本文件来保存文件,使用 key = value, key2 = value2 ,...... 的方式来保存数据.这样做的坏处是结构比较不规矩,读取起来也不方便,需要自行编写一长串的if / else 语句.为了解决这些问题,我们可以使用XML. XML定义了一组规则,即

C#操作XML学习(一)

一.简单介绍 using System.Xml; //初始化一个xml实例 XmlDocument xml=new XmlDocument(); //导入指定xml文件 xml.Load(path); xml.Load(HttpContext.Current.Server.MapPath("~/file/bookstore.xml")); //指定一个节点 XmlNode root=xml.SelectSingleNode("/root"); //获取节点下所有直接

java操作XML文件

XML文件可以用来作为一种小型数据库存在,但更多时候在项目中都是用来当成配置文件用的,也就避免不了对XML文件的增上改查操作. 在java中,解析XML文件的方式大致分为两种:DOM解析,SAX解析 先来说DOM解析方式:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容. 用的较为多的是Dom4j工具(非官方)解析,简单介绍下Dom4j的使用,具体API文档请下载

PHP操作XML详解

XML是一种流行的半结构化文件格式,以一种类似数据库的格式存储数据.在实际应用中,一些简单的.安全性较低的 数据往往使用 XML文件的格式进行存储.这样做的好处一方面可以通过减少与数据库的交互性操作提高读取效率,另一方面可以有效利用 XML的优越性降低程序的编写难度.        PHP提供了一整套的读取 XML文件的方法,很容易的就可以编写基于 XML的脚本程序.本章将要介绍 PHP与 XML的操作方法,并对几个常用的 XML类库做一些简要介绍. 1 XML简介 XML是“可扩展性标识语言(