PLSQL NOTE--------XML generate
在PL/SQL中利用XML ,Oracle提供了几个组件,让开发人员能轻松地利用XML技术。这些组件包括:
1.XML分析程序。即用来分析、构造和验证XML文档。
2.XPath引擎。它是使用Xpath(XML标准的另一个元素)说明语法在内存中搜索XML文档的实用程序。SLT处理器。它在Oracle数据库中支持XSLT,允许您把XML文档转换成其他格式。
3.XML SQL实用程序。可以使用SQL产生XML文档,使您可以在Oracle数据库表格中轻松地插入基于XML的数据。
对于PL/SQL开发人员而言,XML分析程序是最重要的组件。通过它,您可以在Oracle数据库中分析、操纵和转换XML文档。XML分析程序由一套APIs(应用程序编程接口)构成。
===================================================================================================================================================================================
xml generate
生成Test.xml,内容如下
1 2 3 4 5 6 7 8 9 10 |
|
1.生成xml的plsql code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
|
2.将xml encode 成clob 写入文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
3.结合使用XMLDOM和utl_file
这样生成XML文件非常方便,能满足一般的应用了.但是XMLDOM有个缺点,就是一次性在内存中生成所有xml文件内容,然后写入到磁盘文件中.如果
xml文件太大,比如说有个table有几个G,想把它保存成xml文件.这样可能就会出现内存不足,生成文件失败.那该咋整呢?
可能首先想到的是用UTL_FILE去生成文件.
里面的内容全部手动写成xml格式的,然后保存成xml后缀的文件.这样确实可行.但有个麻烦问题时如果一些节点内容含有xml的五个保留字符的话
(&,<,>,‘,"
分别是和号,小于号,大于号,单引号,双引号),我们如果以文本方式打开xml文件是看不到节点内容里面有这些保留字的,都转换成了对应
的&, >, <, &apos,
".节点指定的是上面的Arwen或123,假如有名字(A&r<w>e‘n")则保存到xml文件中应该改成
(A&r>w<e&aposn").如果用xmldom会默认去转换,不用我们管了.如
果用UTL_FILE必须手动写代码去转换.
假如有表staff(name varchar2(30), eno integer),里面有几个G的内容,要转换成开头讲的那种格式的xml文件。
--生成xml的代码其中XML文件的头和尾用UTL_FILE直接写入文件中,节点内容用xmldom生成,然后写到clob变量中,再把clob变量值用utl_file写入到xml文件中。
declare STAFFINFO UTL_FILE.FILE_TYPE; v_temp clob; cursor c_table_info is select name,eno from staff; v_name varchar2(30); v_eno integer; doc XMLDOM.DOMDOCUMENT; doc_node XMLDOM.DOMNODE; root_node XMLDOM.DOMNODE; user_node XMLDOM.DOMNODE; item_node XMLDOM.DOMNODE; root_elmt XMLDOM.DOMELEMENT; user_elmt XMLDOM.DOMELEMENT; item_elmt XMLDOM.DOMELEMENT; item_text XMLDOM.DOMTEXT; begin --xml header STAFFINFO :=utl_file.fopen_nchar(‘DIR‘,‘Test.xml‘,‘W‘,32767);--跟前面说的一样必须先创建一个directory才行 UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,‘<staff content = "name and id">‘); UTL_FILE.FFLUSH(STAFFINFO );--直接写入到磁盘文件中,不会停留在内存中 UTL_FILE.FCLOSE(STAFFINFO ); open c_table_info; loop fetch c_table_info into v_name,v_eno; exit when c_table_info%notfound; --XML节点 doc := XMLDOM.NEWDOMDOCUMENT; xmldom.setCharset(doc, ‘UTF-8‘); doc_node := XMLDOM.MAKENODE(doc); user_elmt := XMLDOM.CREATEELEMENT(doc,‘member‘); user_node :=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(user_elmt)); item_elmt :=XMLDOM.CREATEELEMENT(doc,‘name‘); item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt)); item_text := XMLDOM.CREATETEXTNODE(doc,v_name); item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text)); item_elmt :=XMLDOM.CREATEELEMENT(doc,‘eno‘); item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt)); item_text := XMLDOM.CREATETEXTNODE(doc,‘eno‘); item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text)); v_temp :=‘ ‘; --写入到临时变量v_temp中 XMLDOM.WRITETOCLOB(doc,v_temp); STAFFINFO :=utl_file.fopen_nchar(‘DIR‘,‘Test.xml‘,‘A‘,32767);--以a模式会在文件后添加内容,用w会覆盖之前的内容 UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,v_temp); UTL_FILE.FFLUSH(STAFFINFO ); UTL_FILE.FCLOSE(STAFFINFO ); XMLDOM.FREEDOCUMENT(doc); end loop; close c_table_info; --xml tail STAFFINFO :=utl_file.fopen_nchar(‘DIR‘,‘Test.xml‘,‘a‘,32767); UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,‘</staff>‘); UTL_FILE.FFLUSH(STAFFINFO ); UTL_FILE.FCLOSE(STAFFINFO ); end;