oracle中对小xml文件的解析方法.docx
《oracle中对小xml文件的解析方法.docx》由会员分享,可在线阅读,更多相关《oracle中对小xml文件的解析方法.docx(16页珍藏版)》请在冰点文库上搜索。
oracle中对小xml文件的解析方法
--生成xml层级标签:
xmlelement,null或‘’都会有结束标签,不会出现>单标签
selectxmlelement("test",null)fromdual;
select
xmlelement("aa",
xmlelement("bb",
xmlelement("cc",'1'),
xmlelement("dd",'2')))
fromdual;
--生成xml属性值:
xmlattributes,null或‘’不会出现对应的键名
select
xmlelement("test",123,
xmlelement("a1",
xmlattributes(123456"test_attribute"),
'值1',
xmlelement("a2",
xmlattributes('1'"test1",'2'"test2",''"test3",null"test4"),
'值2')))
fromdual;
--生成层级标签:
xmlforest,如果需要定义标签节点属性则不能使用,null不生成对应节点
--单条数据进行列名匹配取值,生成的标签不一样
select
xmlelement("test",xmlforest(null"test1",1"test2",'3'"test3"))
fromdual;
selectxmlforest(1"performance1",1"test2",'3'"test3")fromdual;
--生成层级标签:
xmlagg
--多条数据,给定标签名,匹配列名对应的值生成多个元素值
withtas((select'1'a,'A'bfromdual)
unionallselect'2','A'bfromdualunionallselect'3','B'bfromdual)
--selectxmlelement("KK",xmlagg(xmlelement("test",a)))fromtgroupbyb;
--selectxmlelement("TT",(
--selectxmlagg(xmlelement("test",a)orderbya)fromt))
--fromdual;
--可以生成无效的xml,xml只能有一个根节点
selectxmlagg(xmlelement("test",a))fromt;
--直接写xml,格式不对会报错
selectxmltype.createxml('12')fromdual;
--rtrim()去右侧空格返回一段字符串
withqas
(select1key,'a'xfromdual
unionall
select2key,'b'xfromdual
unionall
select3key,'c'xfromdual
unionall
select4key,'d'xfromdual)
/*selectx,
rtrim(
xmlagg(xmlelement(e,key||',')orderbykey)
)asconcatval
fromqgroupbyx;
*/
--extract()摘取xml,时间,文本等
selectx,
rtrim(xmlagg(xmlelement(e,key||',')orderbykey)
.extract('//text()'),
',')asconcatval
fromq
groupbyx;
--xmlconcat:
拼接xml元素
select
xmlconcat(xmlelement("x",xmlattributes('123'"xmlns"),xmlelement("y",'10'),xmlelement("y",'20')),
xmlelement("x",xmlattributes('xyz'"xmlns"),xmlelement("y",'20'),xmlelement("y",'10')),
xmlelement("x",xmlattributes('xyz'"xmlns"),xmlelement("y",'60'),xmlelement("y",'10')))
fromdual
--UPDATEXML修改xml标准内容和attribute
--UPDATEXML(xmltype_instance,xpath_expression,value_expr,namespace_expr)
--xml:
1
MartinChadderton
1000
--可以同时修改多个标签内容
SELECTUPDATEXML(XMLTYPE('
1
MartinChadderton
1000
'),
'/DEPT/SALARY/text()',--通过XPath表达式,指定要修改的标签元素
'1100',
'/DEPT/EMPID/text()',
'AA')
FROMDUAL;
--区分大小写
selectupdatexml(
xmltype('
1
MartinChadderton
1000
'),
'/DEPT/SALARY/text()',
'1200'
)
fromdual;
--如果标签元素没有值,则更新该标签的数据时也会无效,这是Oraclebug2962474
SELECTUPDATEXML(XMLTYPE('
1
MartinChadderton
'),
'/DEPT/SALARY/text()',
'1100')
FROMDUAL;
--可通过下面语句解决,重写该标签,找不到对应要修改的标签不会报错
SELECTUPDATEXML(XMLTYPE('
1
MartinChadderton
'),
'/DEPT/SALARY',
XMLTYPE('论文论著其他2'))
FROMDUAL;
--修改属性,找不到对应要修改的属性不会报错
SELECT
UPDATEXML(XMLTYPE('
1
MartinChadderton
3
'),
'/DEPT/SALARY/@taxable','no','/DEPT/SALARY/text()','123')
FROMdual;
--更新为null
--1.
SELECT
UPDATEXML(XMLTYPE('
1
MartinChadderton
1000
'),
'/DEPT/SALARY/text()',NULL)
FROMdual;
--2、
SELECT
UPDATEXML(XMLTYPE('
1
MartinChadderton
1000
'),
'/DEPT/SALARY',null)
FROMdual;
--更新父节点,为null则所有字节点都消失,剩下父节点
SELECT
UPDATEXML(XMLTYPE('
1
MartinChadderton
1000
'),
'/DEPT',null)
FROMdual;
--去除父节点下所有字节点的值(采用通配符)
--1.
SELECT
UPDATEXML(XMLTYPE('
1
MartinChadderton
1000
'),
'/DEPT//*',NULL)
FROMdual;
--2.如果父节点有属性,一定要指出,或则更新不到数据
SELECT
UPDATEXML(XMLTYPE('
1
MartinChadderton
1000
'),
'/DEPT/EMPID/text()',NULL,
'/DEPT/EMPNAME/text()',NULL,
'/DEPT/SALARY/text()',NULL,'xmlns="xyz"')
FROMdual;
--高级应用,指定的namespace_expr下,更新z='10'的数值
DECLARE
XXMLTYPE:
=XMLTYPE('102010');
BEGIN
SELECTUPDATEXML(X,'/x/z[.="10"]/text()','30','xmlns="xyz"')
INTOX
FROMDUAL;
DBMS_OUTPUT.PUT_LINE(X.GETCLOBVAL);
END;
--UPDATEXML可修改非标准xml(根节点多个)
DECLARE
XXMLTYPE:
=XMLTYPE('1020');
BEGIN
SELECTUPDATEXML(XMLCONCAT(XMLELEMENT("x",Xmlattributes('123'"xmlns"),XMLELEMENT("y",'10'),XMLELEMENT("y",'20')),
XMLELEMENT("x",Xmlattributes('xyz'"xmlns"),XMLELEMENT("y",'20'),XMLELEMENT("y",'10')),
XMLELEMENT("x",Xmlattributes('xyz'"xmlns"),XMLELEMENT("y",'10'),XMLELEMENT("y",'10'))),'/x/y[.="10"]/text()','AA','xmlns="xyz"')
INTOX
FROMDUAL;
DBMS_OUTPUT.PUT_LINE(X.GETCLOBVAL);
END;
--删除某个节点
--1.通用做法10.1之前
DECLARE
xXMLTYPE:
=XMLTYPE('10X2010Y');
BEGIN
SELECTUPDATEXML(x,'/a/b[starts-with(c,10)]',NULL)
INTOx
FROMdual;
dbms_output.put_line(REPLACE(x.getstringval,'',''));
END;
--2.10.2及以上(DELETEXML)
--DELETEXML(xmltype_instance,xpath_expression,namespace_expr)
DECLARE
xXMLTYPE:
=XMLTYPE('10X2010Y');
BEGIN
SELECTDELETEXML(x,'/a/b[starts-with(c,10)]','xmlns="xyz"')
INTOx
FROMdual;
dbms_output.put_line(x.getstringval);
END;
--如果有父节点有属性,一定要指出,或则删不了
DECLARE
xXMLTYPE:
=XMLTYPE('10X110X');
BEGIN
SELECTDELETEXML(x,'/a/b','xmlns="xyz"')
INTOx
FROMdual;
dbms_output.put_line(x.getclobval);
END;
--XMLROOT增加xml开头信息,这个目前不支持编码的指定
SELECTXMLROOT(XMLELEMENT("x",dummy),VERSION'1.0',STANDALONEYES)FROMdual;
--XMLCOMMENT增加xml注释EXTRACT('/')在sqlplus显示的时候格式会好看一些
SELECTXMLELEMENT("x",
XMLELEMENT("x1",dummy),
XMLCOMMENT('TestComment'),
XMLELEMENT("x2",dummy)
).EXTRACT('/')
FROMdual;
--XMLCDATA10g之前没有这个函数,CDATA节是用来告诉XML解析器将一切作为数据。
如果你有一个要求发送信息,例如,有很多XML“非法”字符,如&、<和>,
--但不能包含]]>
SELECTUPDATEXML(XMLELEMENT("parent",XMLCDATA('Hereisastringwitha')),'/parent//text()','123')
FROMdual;
SELECTXMLELEMENT("parent",XMLCDATA('Hereisa!
[[stringwitha--如果值为空或null不会生成CDATA
SELECTXMLELEMENT("x",XMLCDATA(''))FROMdual;
/*=====================通过xml获取数据=========================*/
--xmltable
--XMLTABLE(PASSING
--COLUMNSPATH,{PATH...})
select*
fromtt,xmltable('/ipmp/head'passingxmltype(tt.clb_content)
columnsreferencevarchar2(99)path'reference',
busiCodevarchar2(99)path'busiCode')
WHEREclb_contentLIKE'%ipmp%';
--如果字段类型长度比值还短,会进行截取
select*
fromxmltable('/a/b'passingxmltype('112021230')
columnsbvarchar2
(2)path'.');
--不用xmltable的实现方式
SELECT
EXTRACTVALUE(VALUE(t),'/a/b')b,
EXTRACTVALUE(VALUE(t),'/a/c')a
FROM
TABLE(XMLSEQUENCE(EXTRACT(XMLTYPE('1020'),'/a')))t;
--指定返回类型
SELECT*
FROMXMLTABLE('/a/b'
PASSINGXMLTYPE('10')
COLUMNSb_as_varchar2VARCHAR2
(2)PATH'../b',
b_as_xmltypeXMLTYPEPATH'/',
b_asVARCHAR2(3)PATH'.');
--获取属性
select*
fromxmltable('/a'passingxmltype('1020')
columnsbvarchar2
(2)path'b',
battrvarchar2
(1)path'b/@battr',
cvarchar2
(2)path'c');
--获取指定命名空间的相关标签
selectt.b,t.c
fromXMLTABLE(XMLNAMESPACES('namespace2'AS"ns1"),
'/t/ns1:
a'
PASSINGXMLTYPE('aabb1020')
COLUMNSbVARCHAR2
(2)PATH'ns1:
b',
cVARCHAR2
(2)PATH'ns1:
c')t;
--获取指定不同命名空间的相关标签,如果xml里面有指定,在获取的时候也要指定,否则取不到数据
selectt.b,t.c
fromXMLTABLE(XMLNAMESPACES('namespace1'AS"ns1",'namespace2'AS"ns2"),
'/ns1:
a'
PASSINGXMLTYPE('1020')
COLUMNSbVARCHAR2
(2)PATH'ns2:
b',
cVARCHAR2
(2)PATH'ns1:
c')t;--如果节点下有相关的标签,则可以通过下面去获取各自的值
--12c
SELECTc.ref,c.val
FROMXMLTABLE('/a/b/c'
PASSINGXMLTYPE('[1]102030')
RETURNINGSEQUENCEBYREF
COLUMNSrefINTEGERPATH'../ref',
valINTEGERPATH'/')p
--12c以下
SELECTp.ref,c.val
FROMXMLTABLE('/a/b'
PASSINGXMLTYPE('[1]1102030')
COLUMNSrefINTEGERPATH'ref',
cxmlXMLTYPEPATH'c')p,
XMLTABLE('/c'
PASSINGp.cxml
COLUMNSvalINTEGERPATH'/')c
---XMLEXISTS11g以上才有XMLEXISTS(PASSING)判断xml是否存在节点
WITHxAS(
SELECTXMLTYPE('')aFROMdual
)
SELECTCASEWHENXMLEXISTS('/a/c'PASSINGx.a)THEN'TRUE'ELSE'FALSE'END
FROMx;
--带命名空间
WITHxAS(
SELECTXMLTYPE('')aFROMdual
)
SELECTCASEWHENXMLEXISTS('declarenamespacens1="abc";declarenamespacens2="q";(:
:
)/ns1:
a/ns2:
b'PASSINGx.a)THEN'TRUE'ELSE'FALSE'END
FROMx;
--例子
WITHtas(selectxmltype('AA')xmlvarfromdual)
selectxmlvar
fromt
whereXMLEXISTS('/CODEVALUE[.="AA"]'PASSINGxmlvar);
WITHtas(selectxmltype('
|
ClaimCause
1
A
|
Claim
1
AA
|
Y
Rema